Wednesday, 27 July 2016

Structure-like std::tuple usage


While reading P0095R0, WG21* I stumbled upon a cool trick. If you define following structures:
  struct x { double value; };
  struct y { double value; };
  struct z { double value; };

  using point = std::tuple<x, y, z>
you will then be able to write:
  auto x = std::get<x>(point);
  auto y = std::get<y>(point);  
  auto z = std::get<z>(point); 
Look at that! Now we can use std::get<x> to fetch the 'x' value of the tuple, std::get<y> for 'y' and so on, instead of plain, old (and ugly...):
  using point = std::tuple<double, double, double>

  auto x = std::get<0>(point);
  auto y = std::get<1>(point);  
  auto z = std::get<2>(point);
Cool, isn't it?

But the author dismisses such tricks on the spot:
"Should we use this approach everywhere and deprecate the use of struct in any context? In the author's opinion we should not. The use of wrapper types is much more complicated to both read and understand than a plain struct. For example, the wrapper types that were introduced, such as the 'x' type, make little sense outside of their corresponding tuples, yet they are peers to it in scope. Also, the heavy syntax makes it difficult to understand exactly what is intended by this code."
...on the premise that it is too clever. Come on, that little bit of extra code in one place, and then this readability all over your source code? But wait, it comes even harder:
"While the utility of type selection and SFINE for visitors is quite clear for advanced C++ developers, it presents significant hurdles for the beginning or even intermediate developer. This is especially true when it is considered that the visit function is the only way to guarantee a compilation error when all cases are not considered."
That got me thinking. First I wanted to dismiss the argument along the lines of: "what, how can a C++ developer not know what SFINAE is...", but then another thought grew stronger and stronger: "come down from the expert-only, high-church, pure-blood stance, C++ should be usable for beginners too!". Just think about yourself trying to learn an new programming language for a minute. Do you want it esoteric and complicated? Not really. So this is really a show stopper, kind of...

Because, we don't want to give up our freshly discovered syntactic candy so easily, do we?

Thus, I think we need a new syntax extension for C++17 (or C++0y?)**:
  using point = std::tuple<x : double, y : double, z : double>

  auto x = std::get<x>(point);
  auto y = std::get<y>(point);  
  auto z = std::get<z>(point);
Nowadays everybody gets his/hers pet feature added to C++17 (just look at if and switch initializers), so why not?

Come on guys! Who's with me? 


--
* "The Case for a Language Based Variant", C++ Standard proposal P0095R0. It discusses advantages of language based variant implementation vs. a library-only solution.

** of course we could use the brand-new destructuring like in:
  using point = std::tuple<double, double, double>

  auto [x, y, z] = point;
but that's not what we want. We need named access to single elements of the tuple. And don't say we shouldn't use tuple, because we simply want to!

Friday, 15 July 2016

A fairytale found on Stack Overflow


Somewhere on the Internets there is that little fairy tale about a little princess*, written in the
language of dreams, i.e. Javascript:

  function princess() {

      var adventures = [];

      function princeCharming() { /* ... */ }
  
      var unicorn = { /* ... */ },
          dragons = [ /* ... */ ],
          squirrel = "Hello!";

      return {
          story: function() {
              return adventures[adventures.length - 1];
          }
      };
  }

  var littleGirl = princess();
  littleGirl.story();

Can you read it? If not, there is this attempt of translation by Patrick M:
"...the princess() function is a complex scope containing private data. Outside the function, the private data can't be seen or accessed. The princess keeps the unicorns, dragons, adventures etc. in her imagination (private data) and the grown-ups can't see them for themselves. BUT the princess's imagination is captured in the closure for the story() function, which is the only interface the littleGirl instance exposes into the world of magic. – Patrick M Feb 28 '13 at 7:49"  
Still an alien language? Learn some Javascript closures, would you? And then a story unveils:
Domenichino [Public domain], via Wikimedia Commons
Once upon a time, there was a princess, her world was full of adventures: dragons, unicorns, talking squirrels (Narnia?). But because in this world she was only a little girl, she only could tell stories about her adventures. And nobody would believe her, because she couldn't take anybody into her magical land (due to a curse of an old, ugly witch called Ecma). So the princess was both happy and sad, because she couldn't share her adventures with anyone. An that's the tragic of sorcery, you have always to pay a price for it...
Now that you are in the know, did you notice, that the princess doesn't tell anyone about Prince Charming?

--
* source: https://stackoverflow.com/questions/111102/how-do-javascript-closures-work/6472397#6472397