Since a compilation is required before launching a dart application, i wonder if compiler preprocessor is available, or is scheduled in a near future for Dart.
My searches on the net / inside the dart site have proven unsuccessful so far.
( By preprocessor, i mean something like :
#define max(A,B) ( (A) > (B) ? (A):(B))
or :
#define NumType double
#define NumTypeZero 0.0
// used with :
NumType myNum = NumTypeZero;
or :
#define DEBUG
// use
#ifdef DEBUG
print('var1 : $var1, var2:$var2, ...');
#endif
)
Edit : I wonder why there's not allready a pre-processor because it seems we are 'near' from that point :
- Dart has to scan the files for library dependencies to load the libraries in the right order.
- Dart editor also scan files for syntax, type checking and other checks.
- It's possible to have some automated file processing launched within the editor (i couldn't find a valuable link for this, please let me know if you have one).
Basically what the other guys said...
If you're compiling with dart2js, the tree-shaking will already throw out the code inside an if (DEBUG) {} block, if DEBUG is a constant and false. So you can just use if statements.
You can also use assert() statements. The assert, and the expression passed to it will be thrown away when compiling with dart2js for production mode.
So this is actually the same behaviour that you'd get with #ifdefs - you can think of dart2js as your preprocessor ;)
I also don't see any reason why you would want to use #defines instead of constants.
If you want to run your code in the DartVM, you can use dart2js --output-type=dart to do tree-shaking on your dart source.
Update: Also see String.fromEnvironment(), bool.fromEnvironment(), and int.fromEnvironment(). You can set these environment variables when compiling by using "dart2js -D<env-var-name>=<value>".
No, there isn't, and I doubt there will be.
For your first example, the equivalent would just be to define max(a, b) => a > b ? a: b;
Or, more simply import "dart:math";
which includes that already.
The equivalent of the second would be a typedef for NumType, but right now Dart typedefs only work for function types. More general typedefs seem likely to show up in later versions. For the 0.0 part, just const numTypeZero = 0.0;
There is no equivalent to ifdef for conditional code execution right now. However, if at the beginning of your program you defined const DEBUG = false; and wrote if (DEBUG) print("stuff");
that would accomplish roughly what you want.
The things you're looking for are very much C idioms, and often intended for performance. Dart's compiler is quite clever, and does not need some of these.
So, for example, defining max that way is presumably to force it to be inlined. Dart will inline it all by itself if it thinks it's worthwhile, and has the ability to change its mind part-way through execution. Declaring something as "const" makes it a compile-time constant, so is pretty much the same effect as a #define. The ability to reduce the code size by defining symbols like DEBUG is something Dart is missing right now, although conditional compilation is probably more important for other reasons than size. If you're running in a browser, and the compiler is in the browser, then the point of reduced code size is in the download. If you wait until the compiler runs, it's too late, you've already downloaded the code. If you compile to JS ahead of time, it would omit the code in the if statement qualified by a constant false. There's also a dart2dart mode which would do those sorts of transformations, as well as minification on Dart source. But that's less important until there are browsers that are running Dart natively.
From http://blog.sethladd.com/2013/12/compile-time-dead-code-elimination-with.html
Suppose you have code like this:
When compiled with
dart2js -DDEBUG=true app.dart
, the output includes the logging behavior:(the log function is inlined, but the print still happens)
However, if -DDEBUG is not set, the logging behavior is not included in the generated JavaScript code:
At this time there is no preprocessor for Dart. I do not believe that one is planned in the near future either. See Issue 7238
Dart does not require compilation. Only to generate Javascript usable by apps outside of the Dart VM. For instance server side Dart scripts never require compilation. They can generate snapshots to decrease load times but that is less of a compilation step and more storing the state of the VM after the application has launched.
That said, there have been numerous discussions about dependency injection or other dependency management systems based on environment but no consensus or decisions have been reached at this point. See Issue 76
Edit:
1) I hesitate to use the term 'right order' on loading libraries. For the Dart VM itself, it essentially loads all of the library symbols on loading the script and then begins executing the code and matching the symbols to those in the table. The dart2js compiler does something similar but will then also implement treeshaking to try to isolate code that is not used and omit it from the final compilation. But I'm far from a VM or JavaScript compiler guru to have more information on how that process is completed.
2) Similar to other interpreted languages many/most checks are preformed at runtime as opposed to a compile time step. And in fact the Dart VM is designed to run with type checking disabled. It is only enabled for development and actually imposes a significant penalty on the speed of execution.
3) I believe you are referring to the build.dart file. You can find more information at Build.dart and the Dart Editor
Also note that the Dart editor is actually running a dart script called dart_analyzer to validate the code as you type. It is improving but still far from perfect. It does a number of steps to try and assume and associate types and values to the code, but it must also conform to the dart language specification. Thus even if the analyzer is able to assume a type based on surrounding code, it must still provide a warning for instance that type Node has no getter 'value' associated with it, even though the analyzer knows that Node being passed is actually a text input field.