15 ms·
Apple's Module proposal to replace headers for C-based languages [pdf]
- raowarrior 14y agogood idea ,but it is not useful for me , i like traditional programing type of C/C++ ,and my mechines for server are strong enough
- _djo_ 14y agoThis looks promising, aside from being long overdue. Header files have always been one of the more annoying parts of C/C++/Obj-C development. The important bit is that the proposal's ideas for making the transition easier are good and make it seem like this may get traction where similar efforts have failed before. That Doug Gregor and other LLVM/Clang/LLDB developers are already working on the Clang implementation is even better. At the very least we may see this in Objective-C.
- gte910h 14y agoObjective-C is certainly important, but C++ and Objective C++ is where I think this is super important to see. I don't care which solution wins (yet, I might after more inspection/convincing), we just need A solution, and one that works for some older projects with little work.
- tptacek 14y agoIt's been awhile since I did large scale C++, but I remember precision with header file inclusion was a big deal in C++ projects, to the point where you'd mangle your class structure if it'd keep a cascade of header dependencies out of a set of source files. It looks like this module proposal would work at cross purposes to that effort.
- gte910h 14y agoI don't see why this is at cross purposes. The point of this is to do the following transformation to the Big O numbers M x N -> M + N With M being numbers of included headers and N being the number of files including that header. I think that would be solving that mangling of stuff not working at cross purposes. The point is to make it so you go over each file once, rather than multiplicatively many as you do now.
- tptacek 14y agoThat's what the previous best practices (impl pointers and such) did with C++ before; the goal of some of those practices was to minimize the constant factors. I may be misreading how "modules" work, but they seem to accept that sprawling dependencies will get pulled in (if only once).
- Locke1689 14y agoI think the submodule system will help address this issue. People will often import the entire standard library just for one small feature. If submodules are implemented correctly we can reduce that. I'm a little wary at such a major change to C, though.
- gte910h 14y agoThis proposal supports "import std.stdio;" type syntax as well. That seems to greatly help fix the constant part of the equation as well. (In the selection called "Selective Import"). We can't save the world from horrible coders, but selective import would drastically drop the constant costs.
- Someone 14y agoI think it is promising and long overdue, too. It also is clear to me that this will win, because Apple pushes it into LLVM, and has a head start at it. On the other hand: if someone would do the equivalent to their browser, people would call it fragmentation. It will be interesting to see how gcc reacts to this. If this decreases compilation times significantly, I think they will have to follow suit.
- micampe 14y ago> On the other hand: if someone would do the equivalent to their browser, people would call it fragmentation. I haven’t seen many people calling Dart, Pepper, Native Client or the Chrome Web Store “fragmentation”.
- Someone 14y agoWith "the equivalent" I wasn't thinking about creating entirely new ecosystems; I was thinking of tweaking the existing ecosystem to favor one's own tool chain. The moment somebody writes the first module, the world sees the first 'best compiled with clang' code. Once that code uses #import to improve compilation speed, that could become 'must be compiled with clang'. That, IMO, is similar to adding an extra tag to your browser's HTML dialect and then promoting its use. I expect Apple is aware of the risk and wants to to prevent this (the fact that they plan a 100% compatible middle step is an indication of that), but the risk is there. Also, people have argued that the effort spent on Native Client should be spent on improving JavaScript performance because of the fragmentation issue. Responding to another comment: people also have complained about the gcc-isms present in lots of open source libraries.
- micampe 14y agoThe ecosystem is the www, not Javascript and HTML, so those are all tweaking and extending the ecosystem. The moment somebody writes the first Dart or NaCl based website or the first Pepper plugin, the world sees yet another (not the first) "must be viewed with Chrome".
- rjzzleep 14y agolong overdue indeed, reminds me a lot of google go?
- stcredzero 14y agoGolang should get a kickass debugger before C++ gets modules and steals their thunder.
- danieldk 14y agoAnd some would argue generics...
- msbarnett 14y agoGenuinely curious: what are you looking for in a "kickass debugger" for Golang that isn't already provided by GDB's golang support?
- stcredzero 14y agoThe ability to recompile code in the debugger and continue execution?
- pjmlp 14y agoDon't forget generics
- frou_dh 14y agoI found the Go module (aka package) system subtle to understand, but it seems to work well. The subtlety being that what you name when you write "import" is not a module, but a directory on the filesystem (under a known root). Actual module names that act as the namespace for a module's public identifiers do not have to be the same as (or derived from) the import path; that is just the convention. For example, importing "utils" could conceivably bring in bobsfunkystuff.SomeFunc with there being no such module as utils and hence utils.SomeFunc. It's also my understanding that there are no "submodules" in Go. If you want what's in the import path "foo/bar", importing "foo" is unrelated. In fact, there might not be anything in "foo", making it an invalid import path, despite "foo/bar" being a valid one. And then there's the stuff with being able to directly import code from github, code.google.com, etc, but that dovetails in to the same mechanism after downloading.
- pubby 14y agoEveryone wants modules but nobody can agree on how they should behave. This is why they weren't included in C(++)11.
- kibwen 14y agoSpeaking as someone who doesn't follow the development of those specs, can you elaborate? What behaviors are contentious?
- pubby 14y agoI actually haven't been following modules at all so I couldn't tell you exactly what's the problem. Watching from 30:40 of the following video may be insightful though: http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Interactive-Panel-Ask-Us-Anything- http://channel9.msdn.com/Events/GoingNative/GoingNative-2012...
- dubcanada 14y agoApple has a lot of pushing power, probably enough to get this added. At least partially.
- jeremyx 14y agoSince these are not in C++11, we'll have to wait 10 years...
- octopus 14y agoActually you'll have to way from 2 to 5 years. Have a look at Herb Sutter's talk about "The Future of C++": http://channel9.msdn.com/Events/Build/2012/2-005 http://channel9.msdn.com/Events/Build/2012/2-005
- pjmlp 14y agoOnly one major feature is planned to make its way through C++17, modules is considered a major feature. And there are lots of people interested in other sets of major features. So who knows if C++17 will include it, and even it does, how long one can use it in production. Until 2017 many native developers might just had moved into Rust, D, Go or whatever comes along. Just look how computing used to be 5 years ago.
- kibwen 14y agoDo you have a source for "Only one major feature is planned to make its way through C++17"? Wikipedia tells me (without citations) that C++14 and C++17 are minor and major revisions respectively, but doesn't indicate that "major revision" stipulates only a single major change at most.
- pjmlp 14y ago<quote> Bjarne believes that for C++17, we only have resource for 1 major feature, 2 medium features, and a dozen minor features. </quote> https://www.ibm.com/developerworks/mydeveloperworks/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/the_view_from_c_standard_meeting_oct_2012196?lang=en https://www.ibm.com/developerworks/mydeveloperworks/blogs/58...
- smackfu 14y agoPractically Apple will probably add it to Objective C next year.
- crncosta 14y agoAlmost like the way D programming language handle it http://dlang.org/module.html http://dlang.org/module.html
- kibwen 14y agoFor completeness, here's how Rust handles modules: http://dl.rust-lang.org/doc/tutorial.html#modules-and-crates http://dl.rust-lang.org/doc/tutorial.html#modules-and-crates Browsed golang.org for a bit and didn't find any info on how Go handles modules/packages. All I know is that it has something to do with the folder hierarchy of your project (links appreciated).
- acomjean 14y ago
- thwest 14y ago"Apple's Module proposal..." Is Apple really who deserves credit here? Is there something I missed about Apple's management driving this, and not Gregor or the C++ standards committee?
- strmpnk 14y agoFirst slide. It seems like he's employed by Apple and being paid to work on this. So yes, I think calling it Apple's solution an apt description.
- thwest 14y agoHerb Stutter heads the C++ standards committee and credits his employer Microsoft [1]. Is C++11 or C++17 "Microsoft's"? [1] http://isocpp.org/std/the-committee http://isocpp.org/std/the-committee
- jlarocco 14y agoThe standards don't belong to anybody. Particular proposals are credited to the person or organization that propose them. This particular proposal is from Apple. When Herb Sutter/Microsoft make proposals for C++, it's phrased as "Microsoft's proposal for C++0x" or whatever.
- bonch 14y agoDoug Gregor is an Apple employee. They also have a major investment in Clang and LLVM and drive most of its development.
- rplacd 14y agoIf you want a little more precision, credit it to the Apple Compiler Group - they seem to operate with quite a bit more autonomy than, say, whoever's responsible for security there.
- mtdev 14y agoLooks like the core issue is a poor preprocessor implication. It's a good idea in principle, however, we would be adding new features to address shortcomings in existing features instead of fixing the problems in the existing code.
- aaronblohowiak 14y agoBackwards compatibility is a Big Deal for these communities.
- mtdev 14y agoYou can maintain backwards compatibility while fixing bugs. It's equally a Big Deal to have discipline while working on language architecture to minimize feature creep/bloat.
- deleted 14y ago[deleted]
- mbrubeck 14y agoNo, the issue is not just poor implementation. Problems like O(M*N) bloat and scope pollution are fundamental design flaws with the preprocessor header system. Almost every widespread modern language (all except JavaScript? [1]) has a built-in module system. Adding modules to C is not just some sort of hack to work around preprocessor limitations. Instead I'd say that the C preprocessor is a hack to work around lack of modules. [1] and modules will probably be added to JS in the next edition of the ECMAScript standard: http://wiki.ecmascript.org/doku.php?id=harmony:modules http://wiki.ecmascript.org/doku.php?id=harmony:modules
- mtdev 14y agoYou can add some functionality to limit scope and implement a caching system (which is also proposed here) to deal with M*N issues with a focus on keeping backwards compatibility. E.g. the caching is done automatically, the scope spamming control is a best effort solution based on static analysis (for example). Moving from headers to modules is a fundamental change in how the language operates and is guaranteed to further break compatibility between compilers further. I worry that jumping to add these features to the language standard is premature and we should instead look further to optimizations within the preprocessor and linker to see if we can improve performance first.
- meaty 14y agoIt the risk of starting a fight, I really don't want this. I'm quite happy with headers and know how to effectively manage them without shooting myself. Granted there is some compiler overhead for importing large header files but I don't really notice it at all. Also, we already have an Apple/Next non-standard C extension (objective-C). I don't think we want anything else added without proper standardisation regardless of the motivation. I'd rather they forked the language.
- msbarnett 14y ago> Also, we already have an Apple/Next non-standard C extension (objective-C). I don't think we want anything else added without proper standardisation regardless of the motivation. I'd rather they forked the language. This is confusing. Surely Objective-C, which adds a hell of a lot that C does not address and many syntax and runtime changes to support it, would fall under the definition of "fork of the language", rather as C++ does, rather than simply a "non-standard C extension" (surely that description better applies to the many GNU C extensions in GCC?). Re: "adding things without proper standardization", the role of standards committees is to reach consensus among vendors so that they can standardize non-standard extensions that they have variously implemented and tested in the real world first. To argue for the opposite, that the vendors must do nothing until the committee hands down the One True Way from On High, untested outside of their heads, is the height of Design By Committee.
- meaty 14y agoWell Objective C was a preprocessor extension as this proposal is so it's one and the same. Both are extensions. Yes we all know where vendors that do that got us: -moz-gradient: -ms-gradient: gradient: -webkit-gradient: Oh and Microsoft with their C++ CLR extensions and middle finger to C99.
- msbarnett 14y ago> Well Objective C was a preprocessor extension as this proposal is so it's one and the same. Both are extensions. This is daft. Objective-C has been implemented using a full-fledged compiler for decades. Is C++ "just an extension to C" because it was once a pre-processor on top of C? Is Common Lisp "an extension to C" because ECL transforms it into C? Utter lunacy. > Yes we all know where vendors that do that got us Yes; they got us tried and tested ways of implementing things like gradients, so that the standards body had something in the real world to base a successful standard off of. The alternative gets us things like C++98's export templates: unimplementable garbage that no vendors could support because they were invented on paper and any attempt to actually build them in the real world caused more problems than they solved. And just so we're clear what's going on here: The linked slides are about LLVM's implementation of Daveed Vandevoorde's proposal to the C++ committee (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3347.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n334...). The C++ Standards Committee held off on adopting that proposal for C++11 because there were no implementations of it, and asked that vendors try implementing it, adapting it as necessary to make it feasible, and provide feedback so that informed decisions based on experience could be made in the final draft of C++17. Let me repeat that: LLVM is doing exactly what the standards committee asked them to do.
- deleted 14y ago[deleted]
- msbarnett 14y ago> The article is disingenuous. Alongside its oh-so-sassy table of file sizes for helloworld, it needs a table of runtimes for helloworld. Turning stdio into an API instead of preprocessor soup is going to blow that up, unless the guy means something very unusual by "API". You seem to be deeply confused here. This is simply a proposal for persisting the AST for eg) stdio across compiler invocations instead of reparsing it on every textual substitution of a #include, and isolating source AST changes from erroneously corrupting header ASTs. It has no runtime implications because the outputs of the linking stage will be identical. stdio's preprocessor soup is its API. You seem to be the one with an unusual and much narrower meaning of "API".
- Evbn 14y agoHow is this new thing different from precompiled headers, which Apple has had for 10 years?
- nkurz 14y agoWhile LLVM authors probably know best, I don't understand some of his criticisms on the "Inherently Non-Scalable" slide. • M headers with N source files -> M x N build cost It's only MxN if there is no use of the "#ifndef _HEADER_H" workaround that he mentioned earlier. Wouldn't adding a preprocessor directive like "#include_once <header.h>" solve this? Alternatively, these guards could be added to the headers themselves without changing the preprocessor. This probably should be a parallel set of headers (#include <std/stdio.h>) to avoid breaking the rare cases that depend on multiple inclusions, but creating that set would be a simple mechanical translation. • C++ templates exacerbate the problem I'm mostly a C programmer, so I have no argument here. • Precompiled headers are a terrible solution Why is this? It likely would break the ability of headers to be conditional on previous #define statement, but since the proposal does this anyway it doesn't seem insurmountable. Along that lines, how does this proposal handle cases where one needs/wants conditional behavior in the header such as "#ifdef WINDOWS" or the like? And is caching headers during the same compilation also "terrible"?
- deleted 14y ago[deleted]
- VMG 14y agoIt's only MxN if there is no use of the "#ifndef _HEADER_H" workaround that he mentioned earlier. There still is a processing cost for evaluating the instruction
- lttlrck 14y agoFor GCC this is highly optimized: "The preprocessor notices such header files, so that if the header file appears in a subsequent #include directive and FOO is defined, then it is ignored and it doesn't preprocess or even re-open the file a second time. This is referred to as the multiple include optimization." http://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html http://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html
- pjmlp 14y ago
- jheriko 14y agothe one problem i agree with him on is performance - from what i can see his proposal does something to potentially improve that, but its not clear. i worry that caching pre-processed files is a red herring - its it really faster than re-including? what about preprocessor states? what about macros in include files? etc. i feel that the preprocessor ultimately ends up with the same amount of work, just an extra pass for each included header to build a version to be cached… not to mention the complexity required to handle the multiplicity of pre-processor states required for this. maybe i am being dim and missing the obvious. tbh, i'd rather they made their compiler work properly, like respecting alignment on copies with optimisation turned on, or implementing the full C++ 11, before adding language features to fix problems that nobody really has.
- msbarnett 14y ago> i worry that caching pre-processed files is a red herring - its it really faster than re-including? For future reference: In large C++ projects, it's not at all unusual for greater than 90% of the compile time to be spent parsing (and re-parsing, and re-parsing, and re-parsing, ad nauseam) header files. > what about macros in include files? The AST of the header is persisted. If the parser can parse macro definitions, macros will continue to work normally. The only case where you would need to fall back to #include is those rare times in which you want defining something in the source file to alter the parsing of the header (and even in most of those, you should just define the constant in the call to the compiler eg) "clang foo.c -DWITH_FEATURE_X") > i feel that the preprocessor ultimately ends up with the same amount of work, just an extra pass for each included header to build a version to be cached… not to mention the complexity required to handle the multiplicity of pre-processor states required for this. maybe i am being dim and missing the obvious. The pre-processor merely slurps the text of the included file into the including file; the compiler then parses the entire gigantic soup of <text of source file> + <text of all files included by source file>. The semantics of this require that every included header be re-parsed once per compilation unit. Imagine you have 5 .cpp files, each containing 200 characters, and each #including iostreams (which weighs in at roughly 1 million characters). Each .cpp file, post-preprocessor phase, will be 1 million, 200 characters long. A full compilation of the project will require the parsing of 5 million, 1 thousand characters. Any subsequent full build will require parsing the full 5 million, 1 thousand characters. Changing one .cpp file will result in the need to parse 1 million, 200 characters. In this proposal, by contrast, an included file need only ever be parsed once; its AST can then be persisted and referenced eternally. In our above example, the iostreams header will be parsed once, and each .cpp file will be parsed once. This means a full build, the very first time iostreams is ever referenced in any compilation on the system, will require parsing 1 million, 1 thousand characters. Any subsequent full build will require parsing merely 1 thousand characters. Changing one .cpp file will require parsing merely 200 characters.
- acomjean 14y agoI thought one of the points of headers system was you could use the code without having to slog through all the source. Thinking about my trips to /usr/include, those headers weren't that useful for coding with but you could get constants and function names at least.
- Too 14y agoC# together with visual studio solves this in an amazing way. You can browse .NET DLL-files as if they were source files, with only public members being visible and without the function bodies. Good for finding function names and constants. I can't believe nobody else is using the same system, using "go to definition" on a library function is just as natural as using it on one of your own functions. Only difference is in the second case you see the actual code of the function instead of just the function header. (Replace .NET DLL-files with these new "modules" to make this applicable to C) Ps. even if you do have the source, in most editors you can collapse the code to hide everything so you don't have to "slog through all the source".
- richy_rich 14y agoMost (all?) Java IDEs do this as does XCode ( Obj-C) and probably many other things. This isn't the point here though...
- Evbn 14y agoBut Eclipse does stupid stuff like disabling Ctrl-Ffull text search when viewing a .class file, even though text method names are plainly visible.
- haberman 14y agoOverall I like it. I like how they are treating both C and C++ as first-class citizens of this new feature (instead of, for example, inextricably tying its design to classes and namespaces). I like that they have a plausible migration story for how to interoperate with existing header files. And the overall design really looks like something that would fit into all of the C and C++ work that I do without getting in the way. Sure it's non-standard and no one who cares about portability will use this (yet). But this is exactly the way that good ideas get refined and eventually standardized. You surely wouldn't want to standardize a module system that hadn't been already implemented and tested -- that would just leave you with surprises when theory meets reality. C and C++ are here to stay -- we should be open to improvements in them. They don't explicitly mention this, but I'm sure that they have no plans to remove existing #include functionality -- it is a near certainty that someone, somewhere depends on having the preprocessor state affect how an include file is processed. There are probably even cases where you can look at the design rationale for this choice and say "yep, that really is the best solution for what you are trying to do."
- masklinn 14y ago> instead of, for example, inextricably tying its design to classes and namespaces Considering it's Apple-designed and Apple works mostly with C (and Obj-C), it's not really surprising that they designed it for C and working with C++ rather than design it for C++.
- matthavener 14y agoApple uses C++, even on mobile. The iBooks acknowledgements lists Boost and Google Protobufs.
- anextio 14y agoAnd also like... the XNU kernel?
- masklinn 14y agoThat Apple uses C++ (you could also have mentioned LLVM) does not change their production and API being mostly C or Obj-C, and thus their proposals are usually for C. A previous examples was blocks, they created those for C and Obj-C, they can be used from C++ but are completely incompatible with C++11 lambdas as far as I know.
- sev 14y agoThey mention: > "‘import’ ignores preprocessor state within the source file" I wonder if that would remove specific use-cases where you wouldn't want the import to ignore the state of the pre-processor within the source file? Overall, I like it!
- cpeterso 14y agoYou can still use #include if you want preprocessor state to leak into a specific header file.
- jonhohle 14y agoI like the idea, but hopefully they'll shorten the std submodules to `std.io`, `std.lib`, etc.
- georgeg 14y agoIs D not doing this sort of thing already or am I wrong?
- cjensen 14y agoI didn't see any mention of the recursive-usage problem. How do they plan on handling co-dependant files? For example, class A's code makes use of class B. Class B's code makes use of class A. a.h looks like: class B; class A { public: void foo (B *); } a.cc looks like: #include "a.h" #include "b.h" void A::foo (B *) { b->narf (); } and b.h and b.cc use A in the same way.
- SeanLuke 14y agoI don't see what the issue is. In some sense, the proposal is to essentially do away with inserted code and instead do what Java is doing with its import statements: a public API. There's no recursion issue in Java. I think you may be mixing this up with C's #include, which does have recursion issues, hence the need for its absurd #ifdef guards. But Apple did away with that years ago with #import, which is basically #include with built-in guards.
- cjensen 14y agoI'm wondering how it accomplishes this as a practical matter. Does it compile a file twice? Once to create the interface info, and a second time to compile the implementation? Can they even parse enough of a C++ file to generate the interface in all cases? That they chose not to mention the issue makes me nervous that they think they can just ignore the problem. Many previous languages have ignored the problem and said "don't do that." I hope this proposal does not go in that direction.
- cperciva 14y agoI don't buy the performance argument: NxM -> N + M only works if every one of the N .c files is including every one of the M .h files. If you're spamming #includes like that, you need to fix your #includes, not redefine the language.
- greggman 14y agoIt's possible I don't understand the proposal and I'm probably going to get egg on my face and but I'm not sure I really want this. If I wanted Objective C or C# or Java or Python I'd use Objective C or C# or Java or Python. I actually like the preprocessor. I like that I can write code like this #ifdef DEBUG #define DEBUG_BLOCK(code) code #else #define DEBUG_BLOCK(code) #endif void SomeFunction(int a, float b) { DEBUG_BLOCK({ LOG_IF_ENABLED("Called SomeFunction(%d, %f)\n", a, b); }); ... do whatever it was SomeFunction does .. } In other languages that I'm used to there's no way to selectively compile stuff in/out. I like that I can change the behavior of a file for a single include unit -- foo.cc -- #include "mylib.h" -- bar.cc -- #include "mylib.h" -- baz.cc -- #define MYLIB_ENABLED_EXPENSIVE_DEBUGGING_STUFF 1 #include "mylib.h" because enabling it globally would run too slow I like that I can code generate // --command.h-- #define COMMAND_LIST \ COMMAND_OP(Stand) \ COMMAND_OP(Walk) \ COMMAND_OP(Run) \ COMMAND_OP(Hide) \ COMMAND_OP(Jump) \ // make enum for commands #define COMMAND_OP(id) k##id, enum CommandId { COMMAND_LIST kLastCommandId, }; #undef COMMAND_OP // --command.cc-- // Make command strings #define COMMAND_OP(id) #id const char* GetCommandString(CommandId id) { static const char* command_names[] = { #define COMMAND_OP(id) #id, COMMAND_LIST #undef COMMAND_OP }; return command_names[id]; } // make a jump table for the commands typedef bool (*CommandFunc)(Context*); bool FunctionDispatch(CommandID id, Context* ctx) { static CommandFunc s_command_table[] = { #define COMMAND_OP(id) id##Proc, COMMAND_LIST, #undef COMMAND_OP } return s_command_table[id](ctx); }; Or this class Thing { public: void DoSomething(); private: #ifdef USE_SLOW_LEGACY_FEATURE // needs access to Thing's internals. void EmulateOldSlowLegacyFeature(); #endif }; Yes, I can try to hide the implementation but again, the reason I'm using C++ is because I want the optimal code. Not a double indirected pimpl. If I wanted the indirection I'd be using another language. I love C/C++ and it's quirks. I use it's quirks to make my life easier in ways other some other languages don't. Modules seems like is ignoring some of what makes C/C++ unique and trying to turn it into Java/C# People saying the preprocessor has issues are ignoring the benefits. I miss the preprocessor in languages that don't have one because I miss those benefits. You could say, "well, just don't use this feature then" but I can easily see once a project goes down this path, all those benefits of the preprocessor will be lost. You can't easily switch your code between module and include, especially if it's a large project like WebKit, Chrome, Linux, etc. Leave my C++ alone! Get off my lawn!
- vilya 14y agoAnyone know where I can read more detail about this proposal? It looks really interesting, but there are a couple of things I'm not clear on from the pdf: How do you get away from creating a header file for a closed source module? Without a header, how would users of your module know what they can call? Can you perform reflection on a module to inspect it? Is there some kind of tool proposed, like javadoc or pydoc, to generate documentation for a module? How does this work with C++ templates? If you don't know in advance what types the template will be instantiated with, how can you pre-compile the code? I'm sure the authors have thought through all these issues and more; I'd love to read about their solutions.
- Symmetry 14y agoIt looks like the old #include style will still be available where you can't use packages, and it seemed to me that you only needed the .h files for the generation of the modules, not the source .c files.
- aidenn0 14y agoI know nothing about this proposal, but I can make educated guesses on all of these: Creating header: the module needs only the public information for a closed source module. You could generate it from a .h file if you are a consumer of a closed source module, or if you are the producer of the module, you could potentially ship either pre-generated modules or all the information needed to generate a module. javadoc, etc. It sounds like you could generate the information directly from the C/C++ source since there is now information about what is public and private in the source Compiling this: template <typename Type> Type max(Type a, Type b) { return a > b ? a : b; } Generates no code, but it does some work in the compiler that can be cached. This is what would be stored in the module.
- vilya 14y agoThanks, I think you're probably right - the modules would have to have enough information in their compiled form that your compiler could introspect them without needing the source. The proposal wouldn't be much use if that weren't true. Re: templates, I thought the expensive part of template processing was code generation rather than parsing. Would caching the AST really be that much of a saving? I admit I've never tried profiling it to find out...
- zopticity 14y agoLooks like they are trying to rewrite Python.
- rootedbox 14y agoMaybe all the things they figured out in pascal aren't that bad.
- optymizer 14y agoI hear D is backwards compatible with C (and C++?). They already have modules: http://dlang.org/module.html http://dlang.org/module.html . I should use D more often.
- kevinnk 14y agoD is not backwards compatible with C or C++, it doesn't even have a preprocesser. I think what you mean is D code can link C code if you use the C standard libraries.
- optymizer 14y agoYes, I was referring to ABI compatibility. You are probably referring to source-level compatibility. If it's compatible at the binary level, it's compatible.
- jfaucett 14y agoHe's basically just describing a clunkier version of the Go package model
- angersock 14y agoI may come off as a bit nutty here, but do we really want to add another mechanism to C/C++ for something that has been worked with for decades? Most of these issues are things you learn really fast how to avoid in production systems, using things like #pragma once, include guards, and proper symbol and header exposure when writing C libraries. This doesn't really seem like much other than feature bloat for something that works, works well enough, and which probably won't be implemented in a timely fashion by at least 1 major compiler vendor (Hey folks! There's life outside clang and gcc and icc!).
- napierzaza 14y agoWell if you looked they are trying to improve fragility and performance. But I think your real issue is that you banged your head against to wall to learn it so why change it, right? You don't want that since you'd have to learn something new as well as the fact that you already know how to use the old stuff.
- pserwylo 14y agoThis is cool, should make Rusty Russell's CCAN [0] a whole lot more interesting. Instead of just snippets of useful code, it could contain full modules like CPAN/PyPI/PEAR/CRAN/CTAN and various other repositories for other languages. [0] - http://ccodearchive.net/index.html http://ccodearchive.net/index.html
- dpark 14y agoOverall this seems good. The lack of modules in C/C++ is a huge pain. The "link" section seems like a really leaky abstraction, though. module ClangAST { umbrella header “AST/AST.h” module * { } link “-lclangAST” } This hardcodes an implementation-specific syntax and yet says nothing meaningful. Drop the "-l" and you're just restating the name of the module. What value is there in baking a command-line flag into the module definition? P.S. I also find it strange that something intended to blend with C/C++ doesn't use semi-colons. This is just stylistic, though.
- SeoxyS 14y agoI think I'm the only person who likes headers. I'm not overly concerned with compilation times and big-o notation. Computers can compile things really fast nowadays. I'm more concerned with the developer usability benefits & drawbacks of the feature. As somebody who is a polyglot, but spends a large amount of time writing Objective-C, I have come to absolutely love header files. I see header files almost as documentation. To me, a header file is a description of everything that's public about an API. My header files tend to be very well commented, and very sparse, only containing public methods and typedefs. When the need arises to make internally-includable headers (say I'm writing a static library, and have methods that are private to the library, but public to other classes within the library), I will usually write a `MyApi+Internal.h` header for internal use, which doesn't ship with the library. A developer should never have to dig into implementation files, or into documentation, in order to use a library. Its headers ought to be sufficient. Things like private instance variables or anything private does not belong in a header file. FWIW, here's the public header for the library I spend most of my time working on: https://gist.github.com/e83169d2c3984c6f077c https://gist.github.com/e83169d2c3984c6f077c
- nnethercote 14y ago> Computers can compile things really fast nowadays. Not if you're working on a large project. Firefox takes about 15 minutes to build from scratch on my fast Linux box. Getting that down by a factor of 10 or more would be fantastic.
- gilgoomesh 14y agoThe headers still exist. This proposal is not about eliminating them. All this proposal does is bundle groups of headers together and give you a simplified way of including them. If you have a look at the proposed ".map" files, the headers are still fully enumerated. I assume the IDE/debugger will still be able to find definitions in the original header files via the .map files.
- tikhonj 14y agoIt sounds like you'd really like OCaml's module interface files (.mli). Or, more generally, all of OCaml's module system. It's very well designed and definitely worth checking out.
- Executor 14y agoReading this PDF made my day! I can't wait for headerless c/c++. When will this be implemented???
- shadowmint 14y agoSounds interesting, but I've got to admit my initial response is cautious. How will this avoid the LD_LIBRARY_PATH hell of trying to depend on a local module (ie. conflicts)? How will it work at all with local submodules inside a single project? (ie. I have 200 local c files, each with a header. Now what? A module each? How do we handle simple dependencies between classes and functions?) How will we import actual macros? My guess is that the answers are: 1) include path style --module-path=blah Seems fair, but this is going to be as messy as include paths already are. 2, 3) dont use modules except at a system level. Thats a shame as far as im concerned, but perhaps I'm wrong. Can anyone else see how these might work?
- deleted 14y ago[deleted]
- dchichkov 14y agoIt breaks "there should be one-- and preferably only one --obvious way to do it". And quite a few others. But as a stand-alone feature, stateless preprocessor includes could be a nice feature to have.
- Nursie 14y agoAnyone saying 'inherently unscalable' about a feature of a language that's used in as many places as C needs to really think about things... I understand some of the objections, and the import mechanism doesn't sound like a bad thing, though some of the objections are weird - Import only imports the public API and everything else can be hidden - who wasn't doing this for libraries or large code modules anyway? Have static functions at the code module level, 'private' headers for sharing functions within a larger logical module and public headers at the logical module or libary level. Is this too cumbersome?
- pmr_ 14y agoThe problem with implementation hiding is that it is impossible to do well with templates. You will always make all implementation details available to your a user of your header and sometimes the implementation details are a public API themselves (libc++ vector brings in almost all of utility, a bunch of type_traits and so on).
- ludovicurbain 14y agoIf they're willing to fix one problem of C (...), why not fix them all instead ? What's the point of even trying to keep C++ alive when it has been proven countless times that many of its features are useless and problematic to the point where no serious coder uses them ? I'd rather see a language that's actually better than lisp and C - but I guess I'll have to write it to see it.
- albertzeyer 14y agoI once thought about an automatic bullet-proof precompiled-header system. I think this is actually not impossible to implement. When first parsing a header, the parser can take track about all macros it depends on in the preprocessor state. E.g. a very common macro is the one it reads very first, like `#ifndef __MYFILE_H`. Then, including a header becomes a function (<macro1, macro2, ...>) -> (parser state update, i.e. list of added stuff). This can be cached.
- vinayan3 14y agoMy concern is portability because that is the largest benefits of C at-least. C++ portability is less true however it is more portable than most languages.