digitalmars.D - Dlang + compile-time contracts
- Marco Leise (67/67) Jul 31 2017 Coming from D.learn where someone asked for some automatism to
- Martin Tschierschke (15/26) Aug 01 2017 This was the more precise question:
Coming from D.learn where someone asked for some automatism to turn runtime format strings to `format()` into the equivalent `format!()` form automatically to benefit from compile-time type checks I started wondering... The OP wasn't looking for other benefits of the template version other than argument checking and didn't consider the downsides either. So maybe there is room for improvement using runtime arguments. So let's add some features: 1) compile-time "in" contract, run on the argument list 2) functionality to promote runtime arguments to compile-time string format(string fmt) in(ctfe) { // Test if argument 'fmt' is based off a compile-time // readable literal/enum/immutable static if (__traits(isCtfeConvertible, fmt)) { // Perform the actual promotion enum ctfeFmt =3D __traits(ctfeConvert, fmt); static assert(ctfeFmt =3D=3D "%s", "fmt string is not '%s'"); } } body { return "..."; } Note that this idea is based on existing technology in the front-end. Compare how an alias can stand in for a CT or RT argument at the same time: void main() { const fmt1 =3D "%x"; auto fmt2 =3D "%s"; aliasTest!fmt1; aliasTest!fmt2; } void aliasTest(alias fmt)() { import std.stdio; static if (__traits(compiles, {enum ctfeFmt =3D fmt;})) // "Promotion" to compile time value enum output =3D "'fmt' is '" ~ fmt ~ "' at compile-time"; else string output =3D "'fmt' is '" ~ fmt ~ "' at runtime"; writeln(output); } This prints: 'fmt' is '%x' at compile-time 'fmt' is '%s' at runtime For technical reasons a compile-time "in" contract can not work in nested functions so all the CTFE contracts need to be on the top level, user facing code. That means in practice when there are several formatting functions, they'd extract the implementation of the compile-time contract into separate functions. I have no idea how exactly that scales as the `static if (__traits(isCtfeConvertible, =E2=80=A6))` stuff has to remain in the contract. (It's probably ok.) Extending the CTFE promotion to any variables that can be const-folded is not part of this idea as it leaves a lot of fuzzyness in language specification documents and results in code that produces errors in one compiler, but not in another. Since some people will still find it beneficial it should be a compiler vendor extension and print a warning only on contract violations. </braindump> --=20 Marco
Jul 31 2017
On Monday, 31 July 2017 at 17:54:04 UTC, Marco Leise wrote:Coming from D.learn where someone asked for some automatism to turn runtime format strings to `format()` into the equivalent `format!()` form automatically to benefit from compile-time type checks I started wondering... The OP wasn't looking for other benefits of the template version other than argument checking and didn't consider the downsides either. So maybe there is room for improvement using runtime arguments. So let's add some features: 1) compile-time "in" contract, run on the argument list 2) functionality to promote runtime arguments to compile-timeThis was the more precise question: How to "promote runtime arguments to compile-time". I forgot the exact error, but it was during using vibe.d, that there was an error popping up at runtime, which I thought should have been detected as simple syntax violation already during compile time. Making me feeling for some seconds being back at .php. :) I think it was in a regex, where the use of ctRegex would have prevented me from the runtime error. And last but not least: Thank you Marco for sharing your thoughts and expertise! Regards mt.
Aug 01 2017