[HN Gopher] C++ Pattern Matching Proposal [pdf] ___________________________________________________________________ C++ Pattern Matching Proposal [pdf] Author : je42 Score : 149 points Date : 2020-01-02 07:25 UTC (1 days ago) (HTM) web link (www.open-std.org) (TXT) w3m dump (www.open-std.org) | rb808 wrote: | Its seems all languages are just copying each other at this | point. I know C++ hates to be left out of anything so maybe this | is appropriate, but to me its really destroying the ecosystem. | | It was great to have different languages having different | paradigms but now you can do everything in everything and code | bases I'm working on are a confusing mess. | jokoon wrote: | This is a codebase problem, not a language one. | | If there's a good idea, why not use it? | emodendroket wrote: | I think it's great. No need to switch languages when you just | need some feature here and there. | agumonkey wrote: | > each other | | by each other you mean the ml world right ? :p | vmchale wrote: | Functional programming seems to be taking on the world (J | inspiring NumPy, ML features being used everywhere). | gdxhyrd wrote: | Functional languages are nowhere to be seen compared to the | rest. | | Some subset of features inspired in them are used in some | languages, but that has nothing to do with functional | programming taking over. | agumonkey wrote: | Honestly even if we're far from FP as mainstream (which I | don't even wish). I woudln't have bet a dollar that so | much features from lisp/ml would have crossed over this | fast (I mean destruct, lambda, rest args, immutable let | by default, option chaining ..). | vmchale wrote: | > option chaining | | Where'd that come from? I thought that was monadic-do | from Haskell. | agumonkey wrote: | well I include haskell is the ml family (I admit it's | twisting the words) | dnautics wrote: | With Hooks, React has gone full FP, so, basically, the | war is lost. Try finding a bootcamp programmer that | wasn't taught React. | | Sure, you can still build object components, but it's | informally frowned upon. | agumonkey wrote: | Yes, haskellers will soon be celebrities. | oefrha wrote: | What's the downside of copying the good stuff? I think the | examples aren't confusing at all and are perfectly readable by | anybody. | | Honestly I'll be deeply ashamed as a Python programmer writing | cascading ifs when even C++ gets pattern matching. (Yeah, I | know all the arguments against it.) | typon wrote: | This logic doesn't make sense. If something increases | productivity and code quality, why wouldn't languages copy it? | Ideally languages should also remove unnecessary features, | which is actually the thing that makes C++ a confusing mess: | it's prioritization of backwards compatibility over keeping | complexity low. | pjc50 wrote: | > languages should also remove unnecessary features | | Languages are effectively immutable. Unless you can reach out | and edit every single piece of code that breaks when you | remove a feature, you can't remove a feature from a language. | You can only create a new, almost identical language, and | then spend a decade migrating people. This is what happened | to Python2/3. | | Very few things have been successfully deprecated in C or | C++. Even massive security holes in the standard library. | vmchale wrote: | > it's prioritization of backwards compatibility over keeping | complexity low. | | There _are_ other languages on less-shaky foundations, but | people don 't use them for various legitimate and | illegitimate reasons. | de_watcher wrote: | C++ was always the language for constructing paradigms you | choose with underlying mechanism you want. | pjmlp wrote: | Just like PL/I, Object Pascal, Ada, Lisp,... | | C++ wasn't the first multi-paradigm language, and it won't be | the last. | dgellow wrote: | But in this case, pattern matching seems way easier to follow | and evaluate mentally than the verbose visitor approach already | in the language, or something based on switches/if statements. | That seems to be a good way to reduce the amount of confusing | mess, at least for new developments. | specialist wrote: | We design our languages which then design us. Variant of | Churchill's quote about rebuilding their parliament chambers | exactly as before. | | Maybe think of language design as a search thru an n-dimension | problem space. | | There's the perennial trilemma of functional (LISP), imperative | (APL), and object oriented (Simula), where your new language | lands somewhere within that triangular design space. | | Then add extra dimensions for type systems. Nominal vs | structural vs whatever. | | Then add some more for ideas swiped from declarative (SQL, | VRML, LINQ), stack-based (Forth), REPLs (Logo), constraints | (Prolog), and whatever else people cook up. | | Ya, the churn is nutty making. But it's also awesome at the | same time. | [deleted] | vmchale wrote: | > all languages are just copying each other at this point. I | know C++ hates to be left out of anything so maybe this is | appropriate, but to me its really destroying the ecosystem. It | was great to have different languages having different | paradigms but now you can do everything in everything | | I don't think you _can_ do everything in everything. Try | working with lazy immutable data structures in Rust, for one. | | Or look at Dart - now has "non-nullable types," monadic error | handling (sort of), but of course the whole thing is on shaky | foundations so what's it worth? | [deleted] | ChrisSD wrote: | > Try working with lazy immutable data structures in Rust, | for one. | | Why is that an issue? | vmchale wrote: | Well, it doesn't have the runtime to support laziness | properly. | fctorial wrote: | Why would lazy data structures need a runtime? Some kind | of GC is necessary for immutable data structures, but | wouldn't iterators and generators be enough for | implementing laziness? | vmchale wrote: | > wouldn't iterators and generators be enough for | implementing laziness? | | If you can implement lazy finger trees with iterators I'd | love to see it :) | ChrisSD wrote: | Sure, it doesn't have much of a runtime at all but Rust | does give a firm foundation to build on. Using an | `Option` or the `once_cell` library is pretty ergonomic. | At worse you use a function call to get a reference to | the value instead of using it directly. | DougBTX wrote: | Agreed, Rust can certainly handle lazy evaluation. All | the iterator types for example are lazy, hence the | .collect() method which eagerly evaluates a lazy | collection. | | Hiding the fact that a lazy value needs to be mutated to | initialise it is a little more work (since a nice API | lets the user treat the value as if it doesn't need to be | mutated), but is certainly possible. | vmchale wrote: | > All the iterator types for example are lazy, | | It's not proper laziness as defined in Okasaki's | thesis/book. One needs more complex things like lazy | finger trees. | derefr wrote: | > Try working with lazy immutable data structures in Rust. | | I don't think this is _that_ hard; you "just" need to | construct the data structures as elements of an object-graph | data structure, and then retrieve your data through an | explicit thunk of the object-graph itself. | | In lazy languages the object-graph data structure is | implicit, but that doesn't mean that the Rust version of the | _call site_ code needs to be any more verbose. It's just the | definitions of the data structures themselves that would be | more unwieldy. (And you could probably build some generic | lazy container types and mostly work with those.) | | Think: what Objective-C does with autorelease-pool objects. | steveklabnik wrote: | Here's what immutable data structures look like in Rust: | https://docs.rs/im/14.1.0/im/ | vmchale wrote: | None are lazy, however. | nn3 wrote: | It's like human languages. They adopt useful words from each | other all the time too. Why shouldn't programming languages do | the same? | smitty1e wrote: | Restated, nobody under the sun can write "The last, final | language anyone could ever need." | | Think of programming languages as a seminar where designers | are crafting that Ur-language between themselves, and folks | like me in the peanut gallery look on. | Ragnarork wrote: | What is destroyed exactly by adding a feature to a language | that could easily improve readability (which said language | reaaaally needs), which you can also opt not to use if you | don't like? | jarfil wrote: | You can't opt not to use it if you have to work with someone | else's code which does use it. | Ragnarork wrote: | True, I should have been more precise. | | What I meant is the language does not force this on you as | The Right Way To Do Things(tm) and thus it mostly boils | down to organizing with peers and agreeing on a consistent | set of guidelines (which goes well beyond language | features...) | MaxBarraclough wrote: | There's a very good answer to that question: simplicity, | minimalism, and stability. | | C++ is a huge, complex language. It's probably its greatest | downside. Making it _even more_ complex, should only be done | with very good reason. | | If you doubt this, consider the continued popularity of C, a | thoroughly anaemic language by today's standards, with no | clear advantages over C++ except for its simplicity, | minimalism, and that the language changes _very_ slowly. | Well, that and its existing adoption levels. It 's not quite | the case that every feature C has is also in C++, but it's | very close, and I can only name one exception: variable- | length arrays (an unpopular addition to C) are not officially | supported in C++. | | C++'s complexity means that: | | * It's very difficult to learn. It's extremely difficult to | learn well. It's just about impossible to learn in its | entirety. This isn't an exaggeration. (Andrei Alexandrescu | might be the closest we have to someone who knows _all_ of | C++. He 's a world famous C++ expert. Mortals don't stand a | chance.) | | * Different C++ programmers know (and write in) different | subsets of the language. Good C programmers know essentially | all of C. (I'll admit I'm weak on C's bitfields, and I | couldn't tell you every subtlety of its memory model, but | when it comes to C++, there may be areas of the language I've | never even heard of.) | | * C++ style guides (such as Google's one, or LLVM's one) are | long and complex documents, by necessity | | * We will never have a fully complete C++ compiler that truly | matches the language spec. This undermines the spec; the | language you're _really_ using depends on your C++ compiler. | To put that another way: portability is harmed because | different C++ compilers cannot be relied upon to support the | same language features. | | * C++ compilers are more prone to arcane bugs, than C | compilers | | * Different C++ compilers have different arcane bugs, harming | portability | | * It's far easier to develop tools for C than for C++ | (compilers, IDEs, etc) | | * There are more C compilers out there than C++ compilers, | especially for targets like PIC, or for very obscure | platforms, or for particular needs such as safety-critical | work. There's even a formally verified C compiler | ('CompCert') with near-complete support for C99's features. I | doubt there will ever be a formally verified C++ compiler. | | * C is easier to mechanically reason about; there are more | static-analysis tools for C than for C++ | | * If C++ were simpler it might have given rise to stable | ABIs, the way C has. Instead, even different versions of the | same C++ compiler might not be interoperable. | | * It's less predictable regarding performance. Template | metaprogramming can bloat your binaries for seemingly no | reason. In C however, all features of the language map | naturally to assembly; the programmer can generally predict | roughly what assembly will be generated. This matters to | those working with operating systems, graphics, high- | performance programming, or where side-channel attacks are a | security concern. | | C++ is also faster-moving than C, meaning: | | * It takes more work to maintain your skills for reading | other people's code | | * Code can age. Old code looks different from new code, | unless it's actively maintained, which means work and risks | new bugs. If the language rarely changes, this problem goes | away. | | * If you're developing a compiler, you'd rather a stable | language like C, so that you don't have to make a career out | of keeping up with the latest additions to the language. | Keeping up with the additions to C++ is more than any one | compiler-engineer could hope to do. | | There are very few 'conservative' languages like C (there are | also Scheme and Forth), but it can be a language's greatest | strength. Zig is hoping to be another such language, but | we'll have to see if it succeeds. | | With all of that said, I tend to favour C++ over C, and I | _really_ like pattern-matching. It 's something that cannot | really be 'faked' with templates or macros. (Another personal | favourite feature of mine, named arguments, is similar in | that regard.) I think it's rather silly that the major OOP | languages have until recently completely ignored this | brilliant language feature from the functional programming | world, as if it adds nothing over switch/case. Even D, an | extremely feature-rich language, still lacks pattern | matching. | bluGill wrote: | Almost all languages are turning complete. The only questions | is the syntax: convenience of writing it and how fast it runs | on the machine (either/both compile time and run time) | | When you have a syntax that you like for whatever reasons | (including because you have a lot of legacy code written in it) | it makes sense to extend the syntax where possible to make it | more convenient if you can do so within the constraints of | performance. | jokoon wrote: | I don't understand why some people don't like C++. | | It almost seems like they forget what it means to compile to | machine code. | | I can say I have some sort emotional attachment to python, but I | can't deny that C++ is just a more capable language, but at least | I can admit that I'm just not always competent to always write | C++. | | Like most people say "just use the parts of C++ you need". | zyxzevn wrote: | C++ is for real men https://i.redd.it/s6q46do7ce841.png | dullgiulio wrote: | Thankfully C++ is far from the only language that compiles to | native. | | Many others don't even have the same insane "features". | jokoon wrote: | There are not that many languages with good support that | compile to native. | pjmlp wrote: | Java (yes it does, since around 2000), .NET (NGEN since | v1.0, Mono AOT, IL2CPP, .NET Native), D, Eiffel, | FreePascal, Delphi, RemPascal, Swift, OCaml, Haskell, Lisp, | Ada, Scheme, Basic, Go, Fortran. | | Just a couple of possible languages, there are many more if | we take out the good support constraint. | pjmlp wrote: | I love C++, just would rip off the copy-paste compatibility | with C89 if a genie would give me a wish about what to take out | from the language. | greg7mdp wrote: | Love this proposal! C++ is getting better in leaps and bounds. | vunie wrote: | It's amazing what credible competition can do. If only C had | the same kind of pressure. | eps wrote: | Don't you even dare. C is near-perfect in the simplicity of | its core. You want bells and whistles, you hook up a library. | weberc2 wrote: | Could you refer me to a good/standards-compliant library | for typesafe generic lists, hashmaps, pattern matching, | closures, etc? | huhtenberg wrote: | You are missing the main strength of C - the transparency | and predictability of what machine code gets generated | from the source code. | | When you write "a + b", you won't end up with kilobytes | of machine code just because someone in some header | overloaded the + operator. | | Ditto for template-style generics and overloaded | functions. If you call a function and it doesn't exist, | it won't get auto-generated for you on the fly. You get | an error. You want a function, you define that function. | That's not the flaw of the language. That's its strength. | | Ditto for switch-case constructs. | | Ditto for closures. | | All of these constructs, should they be added to the | language, will result in a compiler generating heaps of | code from a simple code snippet. But this will no longer | be C, because in C what you see is what you get. | Jataman606 wrote: | If you call function and it doesnt exist you get a | warning "implicit declaration of function". Unless you | use additional compiler flags. | huhtenberg wrote: | Not since C99. | | But even regardless of that you still get a linking | error. | weberc2 wrote: | I'm not missing anything, I'm responding to a specific | claim--that libraries allow C to compensate for missing | language features. This is patently false irrespective of | the merits of the features in question. | | That said, I think your entire criteria for determining | whether a language or feature is good boils down to its | intuitiveness to experienced C programmers, which seems | like a particularly poor, subjective criteria and it | probably doesn't actually even hold for C considering all | of the security issues and undefined behaviors that are | introduced by and continue to surprise experienced C | programmers. | | For my money, closures, pattern matching, and templates | (not any implementation in particular) are easy enough to | reason about and much better than the corresponding bugs | they address, but to each his own. | reggieband wrote: | > I think your entire criteria for determining whether a | language or feature is good boils down to its | intuitiveness to experienced C programmers ... | | I see this tired argument over and over. It is especially | thrown out when some esoteric language syntax is | criticized. | | In this case it seems to miss the authors point entirely. | My understanding of his argument is that the C language | maps reasonably well to machine code. Adding new features | to the language could hamper that intuitive mapping | between the language syntax and the actual machine code | generated. | | A valid criticism (which others have made) is that the | actual mapping between C code and machine code on modern | machines is far less intuitive than one might expect. | Another valid response would be a demonstration that | "closures, pattern matching, and templates" can be | intuitively mapped directly to machine code. | | I would be happy if I never see the "you are too blinded | by your own language to understand" argument ever again. | It borders on ad-hominem and extends no benefit of doubt | to the original author. | hayez1 wrote: | >For my money, closures, pattern matching, and templates | (not any implementation in particular) are easy enough to | reason about and much better than the corresponding bugs | they address | | Then write C++ only using closures, pattern matching and | templates outside of the C feature set. | weberc2 wrote: | Oh no, did my previous comments read as an exhaustive | list of issues with C? | atilaneves wrote: | > the transparency and predictability of what machine | code gets generated from the source code. | | This gets said a lot, but unless you're writing C code | for a microcontroller (or a PDP11), that isn't even close | to being true. | | > When you write "a + b", you won't end up with kilobytes | of machine code just because someone in some header | overloaded the + operator. | | You can't overload "+" for integers or floats. If you add | two numbers together, you get what you expect, always. If | they're not numbers, and somehow you expected `a + b` to | work without an overloaded operator, then I don't know | what to say. | | > You want a function, you define that function. | | Then you define it again for another type, then again, | then again... | | Then you write a macro and now your colleagues hate you. | | > All of these constructs, should they be added to the | language, will result in a compiler generating heaps of | code from a simple code snippet | | Not necessarily. | huhtenberg wrote: | > _This gets said a lot,_ | | No, this actually doesn't get said a lot, however the | simplicity of C compilation semantics is one of its | biggest strengths. | | > ... _but unless you 're writing C code for a | microcontroller (or a PDP11), that isn't even close to | being true._ | | Do humor us with an example of a C code that compiles | into something that is "not even close" to what you'd | reasonably expect. | jupp0r wrote: | No, you write macros (duck and hide). | doboyy wrote: | Typesafe generics via a better void* would make me super | happy. There are definitely other quality of life | improvements that could be added or reworked that wouldn't | affect the simplicity too much. | sdegutis wrote: | I'd say Rust is the improvements to C that I've always | been wanting: better type safety, real generics, first- | class closures, and OOP without inheritance, only using | structs to structure data, leaving code execution to just | functions. It's what I hoped Go would become. (Take with | grain of salt, I'm just starting to learn Rust.) | doboyy wrote: | I really don't like the monomorphization approach to | generics (I think that's the concept?), where the | function/struct essentially gets duplicated for each | type. It seems to mess with linkage, increase binary | sizes, and increase compile times. | | Other than that, Rust does seem to be an improvement and | less... stressful to program in. | tick_tock_tick wrote: | You can always role dynamics dispatch yourself | twic wrote: | Dynamic dispatch is in the language too. | use core::fmt::Display; fn | show_monomorphic<T: Display>(first: T, second: T) { | println!("{} then {}", first, second); } | fn show_polymorphic(first: &dyn Display, second: &dyn | Display) { println!("{} then {}", first, | second); } pub fn main() { | show_monomorphic(17, 23); | show_monomorphic("fnord", "slack"); | show_polymorphic(&42, &"quirkafleeg"); // mixed types! | } | | There are things you can do with each that you can't do | with the other, but they are often both viable choices. | billfruit wrote: | C has many rough spots too, especially in organising large | and complex programs. There is always scope for innovation | and improvements. | user5994461 wrote: | >>> There is always scope for innovation and | improvements. | | but not in C because C has no scope | vmchale wrote: | > If only C had the same kind of pressure. | | ATS :p | fluffything wrote: | Who is using ATS in production? | | When I learned it I wondered why would somebody use it | instead of Rust or Idris. | antiquark wrote: | Their example #4.3 won't always produce the same result as the | "if" version, because x==x and y==y could return false due to | operator overloading. | wereHamster wrote: | If you overload the == operator such that x==x is false then I | call UB. Reading and understanding such a codebase would be a | nightmare. | 0xffff2 wrote: | Is it actually UB or just stupid? I've never tried to dig in | and understand C++ at the standards level, so I don't know, | but you don't get to just "call" UB; it has to be UB by the | standard. | Karliss wrote: | By itself it is just stupid. Standard defines | "EqualityComparable" property and which parts of STL | require it to be satisfied. There even some places where it | notes that EqualityComparable property isn't required. It | is much easier to get UB by having bad < operator. | fyp wrote: | NaN == NaN is always false (at least in other languages I | know). | kibwen wrote: | This will be the case in any language that confirms to IEEE | 754 (so, hopefully, all of them (because the only thing | more confusing than properly implementing IEEE 754 is | improperly implementing your own bespoke subset)). This | property of NaN is required by the spec (and is, for | example, why Rust's default HashMap refuses to accept | floating point numbers as keys). | greg7mdp wrote: | There is no x==x in example 4.3. This is like structured | binding where x binds to the first element of the tuple. | specialist wrote: | I _really like_ the proposal for matching values (integral, | strings, tuples). It 's very lispy. Explicit representation | (intrinsics?) of a map used as an expression. | | Though I would prefer the keyword 'choose' over 'inspect'. | | -- | | I have noob questions about pattern matching on (polymorphic) | types. Please humor: | | It's syntactic sugar for std::is_base_of<> (Java's instanceof), | right? | | This is a consequence of C++ (and Java's) nominal type system, | right? | | So is pattern matching on types necessary (useful) for structural | type systems? | | I ask because a friend has been advocating structural typing. | He's more of a language theorist whereas I'm more of a language | mechanic (I don't even rate as a language engineer). While I'm | totally on board with whatever he says, I just hope to better | grasp the changes. | toolslive wrote: | compare this proposal to the pattern matching you get from | Haskell or OCaml and weep. | | for example (OCaml): let imply = function | | (true,false) -> false | _ -> true | macintux wrote: | Pattern matching across multiple function heads (ML, Erlang) is | incredibly liberating. I hear Haskell has it but it's not | idiomatic, and I think Elm doesn't support it at all. | Frustrating. | | I've found half-hearted pattern matching solutions like Scala | quite disappointing. | nv-vn wrote: | OCaml, F#, ReasonML don't support that, I think it's unique | to SML in the ML family. | macintux wrote: | Interesting, thanks. SML is my only direct exposure to the | family, and I recall a conference speaker mentioning that | ML (perhaps SML) programmers weren't fond of the feature. | lalaithion wrote: | Can you give an example of the pattern matching in ML and | Erlang that is not idiomatic in Haskell? | macintux wrote: | It's the multiple function heads which (again, I've been | informed, no direct knowledge) is discouraged. | | e.g. https://github.com/macintux/advent-of- | code-2019/blob/master/... | p0llard wrote: | You mean a piecewise definition of a function? I don't | think this is unidiomatic or discouraged in Haskell at | all. | macintux wrote: | There's some indirect discussion here that seems to | contradict that, but I certainly could be wrong. | | https://github.com/elm/compiler/issues/973 | Iceland_jack wrote: | That's in the context of Elm, Evan gives his reasons but | in the context of Haskell such multi-line equations are | very common and normal Haskell style. | typon wrote: | Why call it inspect instead of match? | Sharlin wrote: | Inspect breaks less existing code. | kevin_thibedeau wrote: | They ought to use "_Inspect". | de_watcher wrote: | Because of regex. | mkl wrote: | The regex header doesn't seem to define anything called | "match". It is probably a common variable name though. To me | "inspect" implies the wrong action, so it would be nice if | there was a better keyword. | crazypython wrote: | How does this work compared to ML's signatures? | thurn wrote: | anything in here about exhaustiveness checking? In my mind that's | half the value of pattern matching. | SloopJon wrote: | From the Exhaustiveness and Usefulness section: | | "inspect can be declared [[strict]] for implementation-defined | exhaustiveness and usefulness checking." | | "having a __: case makes any inspect statement exhaustive." | | "any case that comes after a __: case would be useless" | jobstijl wrote: | Why wouldn't they make it [[strict]] by default? | atilaneves wrote: | Because it's C++, and the defaults must suck | (std::vector::at anyone?) | amelius wrote: | Does the D language have pattern matching? | [deleted] | atilaneves wrote: | No. | | But it can be done as a library. Granted, it's not the same as | 1st class support, but it's pretty good: | | https://github.com/pbackus/sumtype | ape4 wrote: | I know this is different than the regex library but just thought | I'd mention... | | Declaring regex's like javaScript with be cool. | var myre = /^hello\w*/; std::regex myre("^hello\\\w*"); | tambre wrote: | Use raw strings. std::regex | myre(R"(^hello\w*)"); | bstamour wrote: | You can add a literal operator: auto operator | "" _r(char const* str, unsigned long) { return | std::regex{str}; } | | To avoid all the backslashes, you can use a raw string literal: | int main() { auto myre = R"(^hello\w*)"_r; } | 0xffff2 wrote: | Just skimming section 4, this really just looks like _even more_ | syntax being added to the language without enough benefit to | justify the additional complexity. At this point, I think I 've | made the decision to just stick with C++11 indefinitely and | backport the rare useful feature. I don't want to have to | memorize all of this extra stuff. | xscott wrote: | What we need is a compiler flag that says, "give me the good | parts of C++11/14, but leave out the bad stuff from C++98, and | fix some of the inconsistency quirks from trying to be | compatible with C89". | 0xffff2 wrote: | Even given the inevitability of disagreements about which are | the "good parts", I'm pretty sure this would be my "standard | version" of choice if it was available. | zozbot234 wrote: | The "C++ Core" guidelines get pretty close to standardizing | the 'good parts' of C++. | 0xffff2 wrote: | I'm aware of the guidelines and apply them, but that's | only a small fraction of the problem. What I need is a | compiler flag that _enforces_ the guidelines so that I | can write it into my software management docs in place of | "-std=c++11". | [deleted] | karlicoss wrote: | I think core guidelines [0] are aiming that. Some of it is | already supported by tools like clang-tidy, but as far as I | understand the ultimate goal is to have some sort of flag | (e.g. --sane) that would only accept 'reasonable' subset of | c++ and reject legacy stuff. | | However this document is a bit raw, lots of todos, so I'm not | sure how close are we to such flag. | | [0] | https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines | mlvljr wrote: | There is something even better: http://www.open- | std.org/jtc1/sc22/wg21/docs/papers/2019/p188... | | cheers from the shadowland :) | ATsch wrote: | I think the only good way to do this is off of the back of | C++ Modules. Having it as a compiler flag means that all | files in a project, including libraries, must be compliant. | | With C++ modules putting an end to the naive #include, | translation units could specify the C++ specification they | are compliant with, and hence gracefully remove or add new | features on a translation-unit level. | steveklabnik wrote: | This is the idea for the 'epochs' proposal https://vittor | ioromeo.info/index/blog/fixing_cpp_with_epochs... | harikb wrote: | This works so long as entire build is your own code. Once you | get to libraries written by someone else who happens to have | a different "wish list", I would guess this flags idea | wouldn't work well. | falcor84 wrote: | Could you please explain more about the process you're | using? Are you compiling external dependencies as an | integral part of building your own code? | petters wrote: | This is the only sane way of using C++. All C++ | dependencies in the same repo, because there is no | standard C++ ABI. | | I am compiling my C++ codebase with gcc, clang, | emscripten to wasm, visual studio. Impossible if all | dependencies are not present in a "third-party" folder. | | Google's Abseil library is intended to be used this way. | | Otherwise, use the C ABI between dependencies. | gpderetta wrote: | > standard C++ ABI. | | All major OS have a standard, very stable C++ ABI. Some | of them also guarantee a stable ABI for the library | components. | | Of course you cannot use a library built for, say, | Windows on Linux but that's true for all languages. | johannes1234321 wrote: | Assuming all things use the same rtti and exception | settings and all are using same C++ standard library | (libstdc++ vs libc++) | | And then there are other flags - for instance when | gcc/libstdc++ broke std::string in order to switch from a | recounted string to a non-refcounted with small string | optimisation in order to be C+11 compatible ... | | Sure, there are system defaults, but things vary and | often recompiling everything and statically linking | avoids those issues. | jdsully wrote: | For windows that is a _very_ recent change. The ABI used | to change with every compiler rev. | | Further without buyin from the actual standard there's no | gurantee a breaking change won't be forced by the | standard at some point. | pjmlp wrote: | Not for libraries exposed as DLL or COM. | | Although one might argue that is only a C++ subset. | jdsully wrote: | COM is based off of the C ABI not C++. This was done | specifically because C++ does not have a stable ABI. | pjmlp wrote: | There is no such thing as C ABI, rather Windows ABI, | which you can even select several calling conventions, | including Pascal based one. | | COM is based on the way Visual C++ lays out the VMT, and | only masochists use it from bare bones C. | derefr wrote: | They're using some header-only libraries, presumably. | Which, after all, is one of the only _unique_ benefits of | C++ that would lead you to choose it for a green-field | project over, say, Rust. Header-only template libs + | link-time WPO = inlining of template-instantiated | monomorphized methods to their type-strict callers. This | is the feature that leads e.g. LLVM to be written in C++. | steveklabnik wrote: | Rust doesn't have headers, but can still do this. | CreRecombinase wrote: | Anything in your headers is (more or less equivalent to | being) copy-pasted into your own code. Many dependencies | are header-only (which is the only option I'm aware of if | the code is templated). | 0xffff2 wrote: | It's just another standard option. Do libraries that are | compiled with std=c++14 work with application code compiled | with std=c++11? What about the other direction? (I don't | actually know because I do build everything from source.) | You would basically just be adding a new `std=good` option. | CJefferson wrote: | The problem with c++ is many libraries are mostly header | files, and they are combined with your code basically by | cut+paste, so you can't rewlly seperwte libraries from | your own code usefully. | asveikau wrote: | I have seen with clang++ that if I mix and match .o files | built with -std=c++11 and -std=c++17 [something I have | occasionally done by accident] and they reference the | same classes, sometimes they fail to link, not due to | standard library types differing but ones I defined | myself that can compile with either standard. | Sharlin wrote: | Interesting. To me there's very little totally new syntax, and | the benefits are considerable. It's basically just being able | to match on the existing structured binding patterns, as well | as on type tags when the expression is polymorphic. | stinos wrote: | _the benefits are considerable_ | | Exactly. Admittedly with enough modern C++ experience and | having used pattern matching I find the syntax pretty | readable and clear. But even if it weren't I'd probably still | be +1 pattern matching. | voldacar wrote: | If they added proper metaprogramming, people could make their | own pattern matching and other compile time goodies and they | wouldnt have to keep shoving cruft down our throats every 3 | years. | SamReidHughes wrote: | The consequences of using an inspect statement are local to the | statement. So the syntax is a thing to learn, but probably not | a harbinger of language complexity. It's a leaf node. | rightbyte wrote: | Does this proposal have any support? | | At first it seems nice, but is it realistic to add so much new | syntax to the language? | de_watcher wrote: | Structured bindings need to get rid of the mandatory dummy | variables in case of the unused parts of the structure. So | something has to be added. | gumby wrote: | Something has to be added but it could just be an empty | comma, which IIRC parallels initialization: use `auto& [a, , | c]` to match the first and third elements of a tuple. | mikepurvis wrote: | Reading over the examples, it seems like there's a lot of good | stuff here, though I wondered how possible it would be to extend | switch with some of this capability vs adding a new keyword. It | looks like this possibility was considered and is addressed in | SS7.2-- basically the flexibility of case labels and break | statements being able to appear inside control structures leads | to all kinds of chaotic corner cases for switch (Duff's Device | and friends) that are incompatible with the proposed semantics | for inspect, with no obvious way to signal from the source which | one you want. | ramenmeal wrote: | c# has been adding pattern matching capabilities to the switch | statement and I think it's created a mess. Both syntax wise and | possible bug prone. Switch went from choosing a distinct case | to matching multiple cases. I'm sure Mads knows more than me | though, so it's probably a safe change. | jupp0r wrote: | Seems like `inspect` would turn `switch` into a deprecated | practice, which is preferable imho. This way, it's easier to | write clang-tidy rules for conversion and to raise red flags in | PRs. | mikepurvis wrote: | Yeah, it makes sense. It's just a bummer when switch feels | like a much better-named keyword for the functionality, in | the long term. | | You almost wonder if they could do something like how `enum` | got fixed up with proper scoping as `enum class`. Like, could | `switch` retain the legacy functionality with the new stuff | triggered when you do `switch from`, `switch if`, or similar. | Or there could be new keyword added after the parenthesis, | something like: switch(<thing>) cases { | <opt1> : ...; <opt2> : ...; __ : ...; | } | | This has a clear connection back to the legacy command in | terms of a switch always having either case labels or a cases | _structure_. And zero chance of breaking existing code, given | that the `cases` keyword would only be valid in that position | and could still be used as an identifier elsewhere (though | obviously that would be discouraged). | twic wrote: | Or even just have a rule that if a switch uses patterns, it | can't have any of the weird legacy misfeatures. | edflsafoiewq wrote: | switch is an extremely useful control structure, though | needed rarely. It's basically a kind of computed goto, | something not found very often outside C/C++ anymore. | | If there's a real inspect, people will be able to stop | treating switch as a deficient approximation to one, and | maybe appreciate it for what it is. | kabdib wrote: | "It must be our great task, gentlemen, to keep the monkeys away | from the typewriters." | | -- H. L. Mencken | quizotic wrote: | This seems so much more clear to read, with less typing. ___________________________________________________________________ (page generated 2020-01-03 23:01 UTC)