34 comments

[ 2.7 ms ] story [ 72.7 ms ] thread
Very cool. Anonymous types can be really handy in C#, especially when dealing with LINQ to objects code. This looks like it could be a similar fit.
That's surprisingly concise and not too hackish, especially compared to some other techniques I've seen for adding basic reflection to your C++ classes.
This is interesting, but I can't help but wonder at the wisdom of writing C++ in this fashion. What's the use case for this? I perhaps naively think that the problem domains for C++ and Javascript are very different, and that this sort of thing may make sense in the domains where C++ doesn't make sense.

I think I'd be frustrated if I was working on someone's C++ code and I found objects springing up out of nowhere like that.

>What's the use case for this?

job security and returning more than 1 object from a function without return pointers in the args

> returning more than 1 object from a function without return pointers in the args

Actually that’s solved by returning `std::tuple` and `std::tie` – or using custom classes.

Except that it is a bit less error prone. When using std::tie, your have to know the order in which the argument are returned, and you will have bugs the day the maintainer of the library will change it. With iod, you code does not depend on this order anymore.
> using std::tie, your have to know the order in which the argument are returned

How is this any different than needing to know the order in which the arguments are passes? (Which I happen think is a problem that needs solved.)

or just define a struct and return that. named field access, type safe, efficient, IDE friendly. sometimes wonder why people are so keen to do something else.
Yes, the goal is not to replace C++ classes. But I believe that there is cases when passing an object without having to declare a class can save time without impacting the readability of the code.

The other big advantage of this construct it that it provides introspection on objects at compile time, thus allowing to generate super fast serializers and deserializers without having to annotate the class.

I probably should have started out my initial comment by saying thanks for building something and sharing it with the world. I didn't intend for my comments to sound overly critical or like an attack, though at least one individual seems to have gone off the deep end because of them.

Thanks also for taking a bit more time to explain how you see it being used. Between your comments and some of the other constructive replies, it makes more sense to me now.

Thanks for your reflective follow-up post, it's refreshing to see.
For me, testing comes to mind.
That is a laughably narrow worldview. It's even sadder that instead of reasoning out why some domains don't make sense, you direct a burden on the community to persuade you. After matt-42 took the time to create this, present it and share it, you're scoffing at him and challenging everyone else to open up your closed mind. I'm content to leave you confused in the corner, but you've sprayed your little pee on the beautiful garden where I walk each day so I'll give you a tip merely so it smells better to me and the rest my colleagues.

My tip isn't about iod. It's this: Try re-approaching your evaluation of iod with the worldview that IS useful and sketch out some scenarios. If you can show that it doesn't make sense, you'll engage someone intelligent in a conversation. If you won't invest that time in yourself, don't expect anyone else to invest their time in you.

> I think I'd be frustrated if I was working on someone's C++ code and I found objects springing up out of nowhere like that.

That sounds like a personal problem having to do with self-control. You should get a blog.

Speaking of which, the website listed in your profile, c10n.net, is down.

I find your vitriol unwelcome and inappropriate for a discussion that could be and ought to be constructive. I could spend some time explaining my position and defending my previous comment to you, but you haven't earned that.

I will note, however, that questions like the one I posed are in general useful to open up discussion about something new like this. Instead of viewing it as an attack, see it as initiating some exposition on specific cases where this would be useful.

> vitriol > Instead of viewing it as an attack, see it as initiating some exposition on specific cases

And you aren't you taking your own advice because why?

If your comment is supposed to initiate some exposition, then fucking expose away or buzz off and fix c10n.net. All you did was throw up your arms and say "oh, I don't know if this is that great," without even trying it or pointing out why and expect others to fall in line below you and do all the work for you...

And you can see the line of commenters telling you why iod /IS/ a good idea. You could have figured this out on your own, but instead you chose to spend your time getting others to give you the answers.

Ever wonder why they call this website Hacker News and not Manager News?

Asking others to figure out everything for you and report back is unwelcome and inappropriate. Commenting "I don't think this is a good idea, but I'm not going to say why" is unwelcome and inappropriate. You say "I could spend some time explaining my position and defending my previous comment to you" Bullshit. You don't have anything valuable to share except a regrettable knee-jerk reaction after you saw a little JSON in C++.

You even admitted to "perhaps thinking naive." Own up to it. You just tried to cast doubt on something you know nothing about and you're getting called out on it in a more direct way than anyone has ever given you feedback before.

And I don't care if you find me unwelcome. I am, in fact, brutal and I dislike you because you're a lazy bitch who doesn't contribute and can't keep your website running. And I DO have something to say about iod which is more than you have:

I think iod is a brilliant effort. I will enjoy making C++ programs with inline-defined JSON to connect to my server and run it through all kinds of configurations. I don't want to touch Javascript to do that because I think Javascript is shit. Thank you matt-42.

p.s. It didn't compile for me under cygwin with the command line "g++ -std=c++11 example.cc" because the symbol "iod_extend" is missing. I commented out line 42 and it built and ran fine.

How many other fucking people in this thread even TRIED the code? They would have found the same bug as me if they had.

You've managed to break the first two rules in the commenting guidelines [1]; it seems you're in no position to advise anyone on appropriate commenting on HN. Profanity, insults, and personal attacks simply don't belong here. Aside from your childish outbursts, we've had a productive conversation in this thread.

[1] http://ycombinator.com/newsguidelines.html

Where the rule says "Don't say things you wouldn't say in a face to face conversation," you imagine I would not use profanity in a face-to-face conversation.

I will gleefully reiterate everything I've said here in a face-to-face conversation.

I note that you have changed your tune toward the author ("I probably should have started out my initial comment by saying thanks") suggesting you're learning submitters' feelings outrank commenters'. There is hope for you yet.

Please don't make any more personally aggressive comments on Hacker News.
There's absolutely nothing wrong with questioning something that somebody has worked on. In fact, such questioning should be encouraged.

Good ideas and creators will be able to withstand such scrutiny without any problems at all. Bad ones can use it as an opportunity to improve.

> I perhaps naively think that the problem domains for C++ and Javascript are very different

That's just, like, your opinion, man.

I'm a Python / Scheme / JavaScript programmer, and I've touched C++ once, to implement a generic list, and I spent a grand old afternoon chasing template errors. I think I actually got the thing to work, but it was more or less a Monkey-vs-Keyboard type situation. It was at that point that I decided that C++ was too much for my brain.

Frankly I find this hilarious. It looks ideal for hard-coded config information and test data, but the reality is that this wasn't all that complex to begin with...

So, one of the fun applications that I can think of for this is essentially a simple, short Scheme VM along the lines of chapter 4 of Abelson and Sussman.

But yeah, I would take a long, hard look at the situation before using this for real work. But then again, I wouldn't touch C++ for real work in the first place.

A nice usecase is named parameters, usefull when a function is taking lots of parameters, or when the order of parameters of the same type can be switched by error :

  fun(iod(arg1_ = 1, arg2_ = 4)
actually: auto obj = [ x=1, y="foo" ]{};
This just declares a lambda with two parameters with default values. You can't do obj.x, you can't declare "objects" inside of obj, you can't return obj in the parent scope.

Why would you ever do:

  [x=1, y="foo"]{
    // use x, y
  }();
When you can just do:

  auto x = 1;
  auto y = "foo";
  // use x, y

?
I have no idea if it is in the standard, but this actually compile with gcc 4.9 -std=c++1y

auto obj = [ x=1, y="foo" ]{}; obj.x; obj.y;

It is in the C++14 standard:

For every init-capture a non-static data member named by the identifier of the init-capture is declared in the closure type. This member is not a bit-field and not mutable. http://isocpp.org/files/papers/N3648.html

Actually the member can still be declared `private:` and the `obj.a.name` would not be portable. It appears GCC's implementation to make these members `public:` is conforming to c++11 but do not rely on this behavior.

I've been told in ##C++ that the current C++14 draft says: `An init-capture behaves as if it declares and explicitly captures a variable of the form “auto init-capture ;” whose declarative region is the lambda-expression’s compound-statement`

This change would make the named member access non-conforming

Amazing :) I did not know that you could access lambda capture expressions. This can indeed reproduce parts of iod's features. However, this syntax does not provides static introspection, and does not support nesting properly :

auto obj = [ name = 1, a = [name = 1]{} ]{}; obj.a.name;

test.cc: In function ‘int main()’: test.cc:5:38: warning: already captured ‘name’ in lambda expression auto obj = [ name = 1, a = [name = 1]{} ]{}; ^ test.cc:7:9: error: ‘struct main()::<lambda()>’ has no member named ‘name’ obj.a.name;

that's not syntax not supporting nesting, that's gcc having bugs with nested captures. clang++ does not error on this. (strange, but this does not compile with gcc and clang versions I have currently at hand. It did compile a few weeks ago when I tried it...)
This is awesome! I was just thinking of porting some JavaScript based stuff to C++ and not looking forward to dealing with all my adhoc JSON stuff and having to write classes for everyone of them.
Note that something like this is actually part of C99 (but not of C++ - the C++ grammar was apparently too tortured to support this):

    struct example_t {
        int foo, bar, baz;
    } example = {
        .foo = 1,
        .bar = 42,
    };
    /* unnamed members are implicitly set to 0 / NULL */
    assert(example.baz == 0);
combined with compound literals, you can do stuff like

   example = (struct example_t){
      .foo = 2,
      .baz = 1
   };
   assert(example_cmp(&example,
      &(struct example_t){ .foo = 2 }) == 0);
It's one of C99's neater features, I think. I can imagine C++ programmers liking something like iod.