On Mon, Aug 16, 2010 at 6:13 AM, Graydon Hoare <[email protected]> wrote: > Related to the matter of linkage, I've been ruminating a bit on the current > limited support for compile-time constants. > > The "items" in a rust module are currently functions, iterators, types, and > sub-modules. These are constants, in a way, but they're not the sort a lot > of people think of. In particular there are no "value-like" constant items > such as numbers, strings, vectors, records, tuples. They can only be dynamic > values. If you want to produce one of these -- even if it's always the same > value -- you have to write a function that returns it. > > This is not entirely pleasant. There is room for improvement: > > - Things that *could* be compile-time constants can't be calculated > "once". We wind up putting code in the executable rather than > read-only data, and re-calculating repeatedly at runtime.
'Course, there's no reason you couldn't optimize the function to "return global_constant", but that still involves the call and refcounting overhead. If you figure out how to solve the rodata vs refcounting problem, you could skip the refcounting here too. > - Some values -- say, 0-ary tags -- wind up as functions even > though they'd make more sense as enum-like constant values. This is purely a syntactic issue, isn't it? You can compile either syntax to either implementation. IIRC, Ruby and D both allow one to call a 0-argument function without parentheses. > - Constant-folding is left, at best, to optional compiler passes. It > might be nice to be able to guarantee a certain quantity of it to > language users, done in the front-end. It wouldn't have to be done in the frontend even if the language guarantees it. You'd just have to run a couple passes even at -O0. It only needs to be done in the frontend if you allow these constants to be used as part of a type like C++ does. > Suppose, instead, that we have an item type > > 'const <ty> <ident> = <const-expr>;' > > and we recursively define a subset of the expr grammar as > const-ness-propagating. And we're careful to be sure we mean *compile-time* > constant, not initialization-time constant a la C. Then: It's a la C++. C99 requires static initializers to be compile-time constant in 6.7.8p4. > ... > > - Value-level equality needs to be preserved and/or checked somehow > between compile-time and load-time, rather than just type > compatibility. Compiling a crate with math.pi = 3.14, then finding > you linked against a recompiled crate with math.pi = 3.15, is an > unwelcome situation. We'd need some kind of scheme to guard against > this, or make users somehow aware of the risks. Possibly just > require compilation-unit UUID-identity or CHF-identity if there's > been any constant folding? Or track the constants that were folded > and check equality at runtime link time? Awkward options, all... This bit is separable. I think it'd make sense to say that constants in one crate are runtime values from another crate. If you start inlining functions across crate boundaries, you can re-use the same checking mechanism to inline constants. You'd want a way to let the user control this in case they actually want the crate to be upgradeable without relinking. _______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
