On Saturday, 9 March 2013 at 14:49:36 UTC, d coder wrote:
Greetings

I believe the paper takes a contrived route to criticize "static if". It takes some bad code examples which are not obvious use cases of "static if" and then goes on to say that the resultant code is not good. I think the code example to begin with was not good.

Agreed. Just barely started reading it and it appears they're nit-picking about something they would have trouble with if it was scoped or not, but more importantly they aren't considering something we would do automatically. If you declare in one, you declare in the other, only difference may be a few details like storage types, removing some of the problems entirely; So he's attacking something that could be done in the preprocessor anyways; Or maybe he's attacking bad coding style but isn't expressly saying it?

[quote]
Conditional compilation, the selective inclusion of statements in a translation unit, is a conventional example. Consider a simple example of introducing some declarations, depending on whether the size of some type, T.

  static if (sizeof(T)==8) {
    void fun();
    void gun(int);
  } else {
    void gun();
    typedef tx int;
  }

The semantics of the program are this: if sizeof(T)==8, the compiler will parse the statements in the “then” branch, and will tokenize and brace-match the declarations in the else branch. Those other declarations would be uninterpreted by the compiler.

Note that unlike normal if statements, the braces enclosing the conditionally compiled statements do not introduce a new scope. Those declarations are declared into the scope enclosing the static if block. This difference makes code written using static if harder to read and understand—modulating between static and non-static ifs in a single block provides ample opportunities for confution and mistakes.

The effect of this declaration is to conditionally modify the current scope with a set of new declarations. How can we know, later in the program, which version of gun we should use, or whether tx is defined or not? Any use of those
declarations would also need to be wrapped.

  static if (sizeof(T)==8)
    gun(32);
  else
    gun();
  static if (sizeof(T)==8) {
    long n = x;
  }
  static if (sizeof(T)!=8) {
    tx n = x;
  }

Thus, the use of static_if for conditional compilation is viral.
The impact of conditional parsing on program analysis tools is substantial. While the feature may be easily implemented as part of the translation process, program analysis tools have traditionally struggled with conditional declarations. The inclusion of multiple variants (via, e.g., preprocessor conditions) and simultaneous repersentation within a single program model is still an open problem in the source code analysis communities. Adopting static if will make analysis harder, not easier.
[/quote]

And I'm sure that using the preprocessor keeps things simple right? Geez let's take a C/C++ version of that... Preprocessor tokens may be off, but the point should get across... :P

  #ifdef X
    void fun();
    void gun(int);
  #else
    void gun();
    typedef tx int;
  #endif

 And

  #ifdef X
    gun(32);
  #else
    gun();
  #endif
  #ifdef X
    long n = x;
  #endif
  #ifndef X
    tx n = x;
  #endif

[quote]
We have already heard suggestions of static_for and static_while. Can static_switch be far behind? C++ would become a low-level, unprincipled hackers’ favorite playground. In our opinion, if you want compile-time computation, look to constexpr, which does have a sane and typesafe underlying model.

If we do not provide a static_for, hackers will simply make one out of static_if or fake equivalents.
[/quote]

C++ is just as low level as C, this statement is useless. Being against 'static_for' is kinda dumb since if you think about it, it just unrolls the loop ahead of time instead of optimization, other than that it shouldn't do anything odd. I'll agree not to add static_for only because it's not really needed.

[quote]
The semantics of static_if are to tokenize the branch not taken. If the condition is dependent, as it is in the statements above, then the compiler must not parse either branch. Both branches are tokenized since either one could contain compiler-specific extensions—or both, or neither. That won’t be known until both branches would have been fully parsed.

<snip>

Consider the real world impact of this design choice. The inability of the compiler to parse the branches of the compiler means that the library writer will need to instantiate every branch of the template just to ensure that the syntax is correct and that no spelling errors have been made. Today, this is done, to a large extent, by the compiler
[/quote]

In C++ you need to have EVERYTHING loaded (declarations, etc) loaded before you can compile anything, Unlike in D where all tokens effectively have one meaning as intended, so the whole template issues aren't an issue. Seems like they're just opening their own cans of worms :P

[quote]
The trailing if clause enforces a requirement that T must be convertible to the value_type of I. We most strongly agree that some mechanism is needed for constraining templates, this is particular syntax leaves much to be desired. It is particularly verbose, and leaves the entire body of the template unchecked. The body must only be tokenized because the static condition could guard the instantiation against compiler-specific extensions in the nested code. That fact would only be ascertainable after the entire body is parsed.
[/quote]

Deja-vu, until recently (C++11) when they changed 'auto' to accept any type didn't they have to be super verbose everywhere anyways? Verboseness shouldn't matter in templates so much as it's user code that needs to be clean. Microsoft core teams admit their STL they write and maintain is ugliest and basically illegible to anyone outside the team; Although template structure as C++ is and their STL doesn't help much.

[quote]
The static if feature might also be used to support overloading. Below is an implementation of advance.

<snip>

Because static if only allows for Boolean decisions, overloading on a set of overlapping constraints requires the programmer to write bounding predicates like those above (e.g., input iterator but not bidirectional, bidirectional but not random access, etc...). This model of overloading is brittle, error-prone, verbose, and defines a “closed world”. No other overloads may be considered without modifying the constraints on the existing declarations in order to ensure consistency. Declarations might be condensed using else clauses, but this is only cosmetic.
[/quote]

*gasp* Walter! Did you know static if only allows boolean decisions! My god our static if MUST is be error-prone and brittle, a 'closed world'!

 *Note sarcasm*

I'll agree a modification for handling nested static if's or something could be nice, but it's not unmanageable if you keep it relatively small. Hell what am I talking about? People go above and beyond a language to do stuff I wouldn't even consider, like a full x86 emulator in JavaScript..

[quote]
The use of static if might also be used to reorder data structures for tighter alignment, but this is a potentially dangerous idea that could lead to bugs that are exceptionally difficult to diagnose and fix.
[/quote]

 Doesn't he mean the pre-processor?

  #define max(x,y) x > y ? x : y

  int a = 1, b = 2;
  z = max(a++, b++);

  struct X {
  #ifdef TIGHT
    int x;
    char y[100];
  #else
    char y[100];
    int x;
  #endif
  }

The largest complaint he has is managing tokens and being able to figure out what is what; In short previous bad decisions on the language HE HIMSELF MADE are preventing potential growth of the language making static if in his mind, unmanageable, yet you can do anything with the preprocessor (well, no CTFE...).

Reply via email to