9 ms·
I just don't understand why some people are so fascinated by this. Can you all admit that this is not at all practical? I swear C++ folks like it for the sake o
by anon-3988 2y ago
I just don't understand why some people are so fascinated by this. Can you all admit that this is not at all practical? I swear C++ folks like it for the sake of it. No other engineer do this. Only antiques people or whatever.
Can you imagine an engineer that is adamant on using his mystifying bespoke tool instead of just using a ruler. "But what if I have to measure it in the 4th dimension!?".
I was expecting something simple but good Lord, its kwargs. Not some magical asynchronous runtime.
inb4 there are still corner cases so you can't just say "users don't have to know the implementation details so only one person has to suffer". I bet money this abstraction is leaky.
Why can't you just do this at the language level like any sane person?
- forrestthewoods 2y agoReflection is spectacularly useful and sorely missed in C++ But because this is C++ the committee designs the most insane and terrible version of reflection possible
- SideQuark 2y agoReflection is such an insanely useful tool that pretty much all modern languages have it. As usual C++ is 20 years behind language design and brings terrible syntax. But it is tremendously useful. https://en.wikipedia.org/wiki/List_of_reflective_programming_languages_and_platforms https://en.wikipedia.org/wiki/List_of_reflective_programming...
- sky2224 2y agoIsn't the reason why so many other languages have reflection due to the fact that they essentially have the information there from the get-go? For example, C# and Java have their intermediate language that has a bunch of meta information attached to it already or the info can be added easily if need be. Is C++ not more raw in its compilation process from code to object files? I mean sure, I guess meta-data could be added to the object files themselves for runtime inspection, but if it were really that simple, why wouldn't they have just added it if reflection is indeed that much of a sore spot for the language's purpose? Now, I'd like to add, my understanding of compiler internals is quite limited, so if I'm way off base here, please correct me. Additionally, while I too find reflection useful, I've seen a lot of cases where it ends up being a bandaid for poor design and gives people an all too enticing shovel to dig themselves deeper into a hole of technical debt. When used correctly, reflection can be quite elegant, but I think those cases are seldom advantageous in comparison to a different and likely better design approach.
- arjonagelhout 2y agoWhen I started out programming in C#, I used reflection sometimes to circumvent the language’s design and restrictions. This resulted in brittle and hard to reason about code. Reflection should never be used to do this. So I do think you’re right that reflection can (and will) be abused by beginners if present as a language feature. With that said, I don’t know much about the internals of the C++ compiler, but having built a simple reflection system for C++, I think the important thing is just being able to serialize and deserialize POD structs to and from some representation (e.g. json). For more advanced data, such as images or specific binary (file) formats, it’s easier to write custom writing / reading, encoding / decoding logic.
- harry8 2y ago>I think the important thing is just being able to serialize and deserialize POD structs to and from some representation (e.g. json). For more advanced data, such as images or specific binary (file) formats, it’s easier to write custom writing / reading, encoding / decoding logic. Why not just use a visitor? (Genuine question, not c++ snark).
- Night_Thastus 2y agoPersonally, I write the simplest subset of C++ I possibly can at all times. Loops, variables, classes and the STL library when useful. The more advanced features you use, the easier it is to make subtle mistakes, confuse someone who hasn't seen that feature before, or just make everyone working on the software wary of ever touching it.
- arjonagelhout 2y agoI do the same thing. C++’s feature is incredibly broad, and sprinkling in just a bit too much templating can result in code that is cleaner, but harder to reason about when reading it back after a month. For example, using C++ 20 ranges over simple loops is an example of where brevity and “cleanliness” can reduce clarity because the heavy templating and operator overloading hides what the code actually does. On the other hand, sometimes one can’t avoid the complexity when writing a library that aims to work on many platforms, and with special tricks such as SIMD, as is present in the Eigen library.
- drysine 2y ago>hides what the code actually does. As does any function call.
- f1shy 2y agoGod forbids! I want functions to hide HOW is it done, not WHAT. One thing is abstraction, the other is obfuscation.
- drysine 2y agoWhen you add "actually" to "what" it becomes "how") What the code using C++ ranges is doing is quite clear, but understanding how it is doing it requires some knowledge of how ranges work.
- f1shy 2y ago>> I write the simplest subset of C++ I possibly can at all times. Loops, variables, classes and the STL library when useful. That stating that is not stating the obvious, shows how screwed we are. Indeed, why use things that are not necessary? "Just because you can"? And still I find everywhere programs less than 1000 lines of code, that can be written maybe in 10 lines of python, but in C++ they use templates, inheritance, and the most obscure corners of the STL. Mind you, I do not mean some random github repo. where somebody was just practicing and learning. I mean production software, made "professionally"
- NL807 2y agoHonestly, all I ever want is to be enumerate a struct data member or an enum at compile time, and be able to get the name, type and value of each iterated member. That's it. That's all I want.
- Gibbon1 2y agoWould be happy with a enum that's a named key value. key_enum one_two_three { FIRST = { .name = "first"}, SECOND = { .name = "second"}, THIRD = { .name = "third"}, LAST = { .value = 255, .name = "last"}, };
- uecker 2y agoWhat is wrong with the following? Do you want type more type safety, e.g. linking the enumeration constants to the array? enum { FIRST, SECOND, THIRD }; struct { char *name; int value; } table[] = { [FIRST] = { .name = "FIRST", .value = 0 }, [SECOND] = { .name = "SECOND", .value = 1 }, [THIRD] = { .name = "THIRD", .value = 3 }, };
- gpderetta 2y agoYou still need generic code to link the enum type to its format string, for example for use in std::format or std::ostream. Nothing really difficult, normally all of this is done by hand, which is tedious and error prone, or incorporated in a macro. It would just be nice if there was a standard provided turn-key solution to the problem.
- jcelerier 2y agoI have yet to see a project where there have never been bugs due to someone forgetting to update the metadata attached with the enum when there's a change
- jjmarr 2y agomagic_enum addresses your issue but will absolutely kill compile time on a large project due to recursive template instantiation.
- hyperhello 2y agoAt this point, you should just switch to JavaScript. The desperation to have the simple ease of JavaScript without having to say you're going near "that terrible language" is twisting C++ into ridiculous loops. I'm serious. It's like a bizarre Victorian relic now.
- drivebyhooting 2y agoIs JS simpler than Python? I don’t think so but willing to change my mind.
- hyperhello 2y agoThe syntax? Probably a little. It’s a typeless C. As for what you can use it for, it’s limited to browsers, practically, so not really comparable.
- flakes 2y ago> it’s limited to browsers, practically That massively ignores node.js and all of the many popular backend frameworks built on it today. JS might not be everyone's cup of tea, but it is certainly not limited to browsers, practically.
- dingi 2y agoWhich uses JS made for a browser with some modifications.
- friendzis 2y agoWe don't even write utilities in JVM languages, because spawning whole JVM is generally considered too expensive. Yet there are people who will happily spawn whole web browser and even go as far as recommend doing so. All because they can't even write a left-pad function.
- porridgeraisin 2y ago
- ratmeadow 2y ago> Why can't you just do this at the language level like any sane person? The reality is C++ is a ridiculously complex and legacy-ridden language, with a difficult goal to preserve backwards compatibility. I haven't read the history on the keyword args proposals but I'm guessing they were declined due to a deluge of silly edge case interactions with C++ semantics that became too hard to work around. Like how struct designated initialisers have to be in order of member declaration due to object lifetime rules or something like that. I would recommend trying to not be outraged at the state of C++ these days. It's time to stop hoping that C++ gets the nice features we need in any sort of reasonable manner. The reality of the language is not compatible with much niceness.
- drysine 2y ago>Like how struct designated initialisers have to be in order of member declaration due to object lifetime rules or something like that. It matters in which order sub-objects are initialized - if you have a class with the members A and B, and B takes pointer or reference to A in its constructor and does something with A, A better be already initialized. Sub-objects are initialized in the order of their declaration and having different order of designed initializers would be confusing. In fact, exactly that problem we have in C++ with the list of initializers of base classes and data members in constructors.
- badmintonbaseba 2y agoYou can't easily take the pointer to an other member in a designated initializer. It's still a problem for members that are implicitly initialized by their default member initializer, but that can be sorted out.
- deleted 2y ago[deleted]
- drysine 2y agoI think it is easy enough to be a potential footgun [0]: struct A { A(A*);}; struct B { A a1; A a2; }; void f() { B b{.a1 = A(nullptr), .a2 = A(&b.a1) }; } [0] https://godbolt.org/z/cGaxzh17T https://godbolt.org/z/cGaxzh17T
- pjmlp 2y agoApparently you have not been around many Lisp, Python, Ruby, Haskel, Scala,... folks. This kind of geekyness is surely loved by many, not only C++.
- dxuh 2y agoThis is a nifty little gadget, not a production level feature. C++ lacks a lot of things, but it's objectively cool that you can hack some of them yourself (like kwargs). No one should use this in important code. This is just fun.
- Tsche 2y agoindeed
- cedws 2y ago99% of "modern" C++ is just masturbation and trying to keep up with what other languages had 10 years ago. The introduction of new standards isn't improving any code, in fact it's just causing old code to rot faster as the gap widens between the latest standard and the standards companies actually use. It's obvious to any developer with even a little experience that less is more, complexity is the enemy. C++ continually embraces complexity, it even appears to encourage it as an opportunity to show everybody else how smart you are.
- kzrdude 2y agoExploring like this is a way to get familiar with the feature, explore its limits and inform you on how to use it in the future. It's curiosity, play and learning. It's great.
- DannyBee 2y agoThe fascination i sort of get - sometimes rabbit holes are fun to jump down if you have time. I'm working on a satisfactory node modeling tool for fun, and built one of the stores (I have a few different stores) using CRDT's and added collaborative support over webrtc. Is it practical? The result, yes. The process - no, it's a total waste of time and energy compared to much simpler alternatives. No question. Is it fun? Yes. It has been a lot of fun. Was it fascinating - yes, i learned a lot. So the fascination i get - sometimes people do this stuff to learn more about it, or because they are jumping down a rabbit hole they like, or whatever. At the same time, i totally agree with you that this article presents something wildly impractical as-is. But i'm not sure it was meant to be practical. I hope not, since it totally isn't :) For C++ itself, this is why Google, and others, gave up (on the evolution of the language) after decades of trying. Or at least one reason. C++ exposes all this complexity because it's not willing to break anything, ever. If you go look at the reflection paper, they use one single opaque reflection type, and the whole justification is that baking it into the language is dangerous because we might have to change it and that would break things. They give an example of something standardized in 2003 that would have broken if they gave more specific types. Note this is now proposed for 2026. To me, 23 years before breaking something would be a pretty reasonable thing. Especially if migration can be automated. Worse, this logic unfortunately can be applied generally - if you are never going to break anything, it severely restricts your ability to generate more useful interfaces, because you can't depend on anything that might ever change. Which is of course, a losing war anyway - you won't accurately predict all the things that you will want to change, so either you get it wrong anyway, or you now actually block the language by what you did choose to depend on. So the interfaces will only get worse over time, as you are either restricted by the existing stuff not changing, or because you guessed wrong and became one of the reasons those existing things can't change. This has a very predictable end. For every other language, they would just eventually break things, and figure out how to do effective language migration. When they do, you hope it's for something better enough to be worth it, but that's a product problem, and that the language migration takes care of ~all of it for you, which is an engineering one.
- bluGill 2y ago> C++ exposes all this complexity because it's not willing to break anything, ever. That is also why people use C++ for large complex problems. Not doing that is why python3 took forever to replace python2. When you have a lot of code that works it isn't worth the money to rewrite it if you can help it.
- witx 2y agoIt feels to me that C++ has long become a language for "academic" or compiler-minded people to try yet another thing just for the sake of it or because its fun. Yes reflection eases some issues we have on C++ but the syntax is horrible and clutters the language
- harrison_clarke 2y agoi think it's neat that you can do that i'm going to stick to C, to prevent it from compiling, though
- verandaguy 2y agoI think there's a humour to C++ being like Python in that, left alone, the language's community will almost immediately try and stuff as much syntax as possible into the language. The difference is how much power the community has to turn these syntactic fever dreams a reality. With C++, you get first-class stuff like the STL and even the C preprocessor, and now reflection. With Python, it usually comes down to magic method abuse (see pathlib's use of `__div__`), maybe messing around with metaclasses, and the PEP process (though I think they're pumping the brakes at this point -- walrus was fun, but I really hope PEP 750 doesn't make it in, and it seems to me that it'll stall). You technically have `ast`, but that'll only go so far since unless you really go overboard with your hack, you still have to write valid, parseable Python before `ast` will ingest it.