lesson/1.0-variables.cpp (148 lines of code) (raw):

/* * Copyright (c) 2016, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ #include <fatal/lesson/driver.h> namespace lesson { /** * @author: Marcelo Juchem <marcelo@fb.com> */ LESSON( "variables, part 1/2", "This lesson demonstrates how to achieve, in metaprogramming, something " "similar to the notion of variables in procedural programming." ) { COMMENT( "If you think about a duck typed language, we're used to declaring " "variables by assigning a value to a name." ); CODE( auto x = 10; ); COMMENT( "Whenever we want to retrieve the value stored in that variable, we " "reference it through its name:" ) VALUE(x); COMMENT( "A similar idiom can be achieved for metaprogramming. Take the following " "line, for example:" ); CODE( using y = std::integral_constant<int, 10>; ); COMMENT( "We're also assigning a value `10`, of type `int`, to the name `y`." "\n\n" "The difference is that instead of variables, we're using an alias to a " "type." "\n\n" "Just like with variables, we can also retrieve what's stored in that " "type alias:" ); TYPE(y); COMMENT( "Note that we must use a helper function called `type_str()` to properly " "convert types into their actual string representation." "\n\n" "The type `std::integral_constant`, in particular, can be used to " "represent a constant value. Keep in mind, though, that types are " "immutable, therefore we cannot change the value represented by the " "integral constant `y`." "\n\n" "We don't need to use `type_str()` here because the value itself is a " "constant, not a type:" ); VALUE(y::value); ILLEGAL( "it's illegal to re-assign a value to a constant.", y::value = 99; ); COMMENT( "That's the first thing you should notice about metaprogramming: we don't " "manipulate values. We manipulate types." "\n\n" "Types only exist during compilation, so one could say metaprograms run " "inside the compiler, at compile time, as opposed to regular programs " "which run at runtime, after compilation is done." "\n\n" "There are some types that can represent values, like " "`std::integral_constant`, but that's not necessarily true for every type." "\n\n" "For instance, we could create an alias for the type `void`, or `int`, or " "even `std::string`:" ); CODE( using z = void; using w = int; using k = std::string; ); COMMENT( "A `int` or `std::string` runtime variable is able to store values, yes, " "but as for the types themselves, `int` and `std::string`, they don't " "really represent any values at compile time. Assigning values to them " "only make sense at runtime." ); TYPE(z); TYPE(w); TYPE(k); COMMENT( "The last thing to notice is that types are immutable. Once we assign a " "type to an alias, that alias will always represent the same type." "\n\n" "That's a hint that metaprogramming in C++ works similarly to pure " "functional programming." ); ILLEGAL( "it's illegal to re-assign a type to an alias.", w = long; ); COMMENT( "SUMMARY: metaprogramming deals with types, not values. We can simulate " "values using types like `std::integral_constant` or `std::ratio`. But, " "ultimately, they're just types." "\n\n" "Types are immutable." "\n\n" "Metaprograms run at compile time, whereas regular programs run at runtime." ); } /** * @author: Marcelo Juchem <marcelo@fb.com> */ LESSON( "variables, part 2/2", "This lesson is a follow up to the variables lesson above." "\n\n" "Declarations of types below take place outside of the lesson block for " "reasons outside of the scope of this guide, but they should be considered " "part of it nevertheless.", struct m { int value; }; class n { void method(); }; union u { int i; double fp; }; enum e { field0, field1, field2 }; enum class c { field3, field4, field5 }; ) { COMMENT( "Not only type aliases, but classes, structures, enumerations and unions " "can also be considered analogous to procedural programming's variables:" ); TYPE(m); TYPE(n); TYPE(u); TYPE(e); TYPE(c); COMMENT( "And they can be assigned to aliases as well." ); CODE( using vm = m; using vn = n; using vu = u; using ve = e; using vc = c; ); TYPE(vm); TYPE(vn); TYPE(vu); TYPE(ve); TYPE(vc); } } // namespace lesson {