phobos / tango / ares

kris foo at
Sat Feb 10 18:55:45 PST 2007

Kevin Bealer wrote:
> Lars Ivar Igesund wrote:
>> Kevin Bealer wrote:
>>> Lars Ivar Igesund wrote:
>>>> Frits van Bommel wrote:
>>>>> Which one to use is hard to say at this point. I've been trying out
>>>>> Tango since its release and I like it but I sometimes miss some 
>>>>> parts of
>>>>> Phobos. Whether this is because Phobos is just more familiar to me or
>>>>> actually better is hard to say...
>>>> Note that what you miss that you feel you have in Phobos, is very much
>>>> part of the feedback we would like.
>>> Okay -- I'm really sorry if any of this seems to have a negative tone.
>>> I hesitate to write this since I have a lot of respect for the Tango
>>> design in general, but there are a couple of friction points I've 
>>> noticed.
>>> 1. writefln / format replacements
>>> Concerning standard output and string formatting, in phobos I can do
>>> these operations:
>>>    writefln("%s %s %s", a, b, c);
>>>    format("%s %s %s", a, b, c);
>>> How do I do these in Tango?  The change to "{0} {1}" stuff is fine with
>>> me, in fact I like it, but this syntax:
>>>    Stdout.formatln("{0} {1} {2}", a, b, c);
>>>    Format!(char).convert("{0} {1} {2}", a, b, c);
>> I can't give you an immediate solution for the "length" of the
>> Stdout.formatln, but usually one would use tango.text.convert.Sprint for
>> what you use the formatter for. If you only want to print values, 
>> there are
>> non-formatting ways to do that. We may be able to give you quicker/easier
>> help over our forum if you have followups? May make it easier for us to
>> integrate solutions into our documentation too if needed.
> In the future I'll post this kind of thing on the tango forum, but since 
> this thread is already here:
> I looked at this but doesn't Sprint require something like:
>     char[] foo = (new Sprint!(char))("hello {0}", 123);
> 1. A template instance is needed.
> 2. It creates a new class object (Sprint) -- you can't use a single
>    global one in real code because according to the docs it owns the
>    internal buffer and is thus not thread safe.
> 3. That object contains a new buffer which must be allocated.
> 4. As far as I can tell, it requires almost as much syntax as
>    Format!(char) ( my previous example didn't include the 'new'
>    as shown here: )
>     char[] one = (new Format!(char)).convert("{0}", 123);
>     char[] foo = (new Sprint!(char))("hello {0}", 123);

Inside Format.d, there's a static instance called Formatter. This is 
what's used by Stdout, so it will remain in the library. Thus it's legit 
to use that instead of new Format!(char)  ...  e.g. your example becomes

#  auto one = Formatter ("{0}", 123);

There's also a sprint() method on the Format instance, so you can do 
this where you need to avoid heap activity altogether:

#  char[16] tmp;
#  auto one = Formatter.sprint (tmp, "{0}", 123);

Instantiating templates is fine from the perspective of something like a 
server, but it's definately too noisy/verbose for something like 
pedestrian usage; as you have been pointing out. Sean gave some examples 
of wrappers in a post today, which may prove fruitful.

> I haven't looked at the design of std.format but I would think it only 
> suffers from #3 above, which is not too surprising since you would 
> expect a string generation to require a new buffer.
> Sprint seems like a good solution in something like an XML formatting 
> loop, because you can build one object and its in a function call so the 
> thread safety issue is not critical, you can reuse it many times, but as 
> a drop in for 'std.format' it seemed kind of awkward to me.

Probably :)

More information about the Digitalmars-d-learn mailing list