[just talk] what if implicitly typed literals were disallowed

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Oct 24 12:07:03 PDT 2012


On Wed, Oct 24, 2012 at 06:38:34PM +0200, Adam D. Ruppe wrote:
[...]
> The thread about string and rep had me bring up my library string
> implementation again, and it was shot down because of "auto a =
> "foo";" meaning a would not have the library type.
> 
> It made me wonder: what if we got rid of literals? Well, can't do
> that, we need some kind of building block. But, what if we required
> their use to have a clear type?
> 
> I'm tempted to say literals should only be used when there is an
> explicit type given somewhere

Well, completely getting rid of type inference for literals is a bit
extreme, I think, but I definitely agree with the spirit of your
proposal: literals should NOT be assigned a type beforehand; the
compiler should always look for the best fit in the given context first,
and THEN if nothing else says anything more about the type, fall back to
the default type.

So for example, "f(10)" will correctly infer the type based on f's
signature, and so will f([1,2,3]) where f's parameter may be typed, say,
ushort[] or even real[]. This is particular important when f is a
template function: the compiler should try to find all possible matches
BEFORE falling back to int[]. Currently, it doesn't always do this, so
sometimes you have to explicitly type the literal in order to get it to
match the desired template.

Only when nothing else works (say you wrote "auto x = [1,2,3]") should
the compiler fall back to int[], for example.


[...]
> Why does this matter? Well it gives you a lot of user defined
> capabilities here. Let's combine with the following:
> 
> * make the internal type of the literals a special word. _int
> instead of int for example. Now int is not a keyword - it is
> available to library redefinitions (surely in object.d, but you can
> import your own int if you wanted to)
> 
> * have the library give them the prettier names. this might be
> "alias int = _int;" or it might be struct int { this(_int i) { } /*
> custom functionality */}; in other words you can give complete user
> defined behavior without name conflicts. This can be replaced at any
> time by hacking up your druntime.
> 
> 
> * the requirement of being explicit ensures the internal types don't
> leak out somewhere unintentionally in templates or other auto types,
> so your behavior is always predictable, thus solving the problem of
> the library replacement for string
[...]

I think this is orthogonal to assigning a type to a literal. You could,
in theory, modify the compiler so that a literal like [1,2,3] is typed
Integer[], where Integer is aliased to int in druntime, and can be
overridden by a user-defined Integer. This does not require that
literals have no type at all.

Anyway, on a related topic: another thing that irks me about D literals
is that there is sometimes unexpected implicit copying.  Something like:

	real[] x = [1,2,3];

contains an implicit runtime copy of a compile-time built array [1,2,3]
into x. Ideally, since literals are by definition used only in a single
place, the array being initialized should constructed in-place with the
specified values. The current compiler emits a call to a
literal-construction function at runtime, which is unnecessary overhead
when the literal is small (and literals are usually small, since
otherwise you wouldn't write things that way!) -- it could've been just
a handful of MOV's instead of an entire function call.


T

-- 
Маленькие детки - маленькие бедки.


More information about the Digitalmars-d mailing list