April 20, 2009
Russell Lewis wrote:
> Walter Bright wrote:
>>
>> This is a major revision to Phobos, including Andrei's revolutionary new range support.
>>
>> http://www.digitalmars.com/d/2.0/changelog.html
>> http://ftp.digitalmars.com/dmd.2.029.zip
> 
> Was fwritefln() removed intentionally?  Or should I write up a Bugzilla?  I didn't noteice a mention in changelog.

Sorry. It was removed intentionally along with all functions that manipulate FILE* directly.

Its functional equivalent is File.writefln. If all you have is a handle, use File.wrapFile(fhandle).writefln.


Andrei
April 20, 2009
Russell Lewis wrote:
> Walter Bright wrote:
>> tama wrote:
>>> I tested following code.
>>>
>>> writefln(3 * 4);
>>>
>>> This code doesn't work in the first place:-<
>>
>> Yes, that's one of the breaking changes in the new phobos2. writefln
>> expects its first argument to be a format string.
>>
>> If it isn't, use writeln instead.
> 
> I just hit the same breakage. :(
> 
> Since the compiler can detect this situation statically, shouldn't Phobos just statically redirect the call to writeln() ?

It did for a while. For cleanliness purposes, I thought it was about time to eliminate that. Also, extraneous arguments passed to writef will be ignored, not printed with default formatting.

Andrei
April 20, 2009
Andrei Alexandrescu:
> extraneous arguments passed to writef will be ignored, not printed with default formatting.

That sounds bad:
=> "Errors should never pass silently."
It's better to raise a compilation error. (And if that's not possible, then an exception at run-time. But a compilation error is much better).

Bye,
bearophile
April 20, 2009
bearophile wrote:
> Andrei Alexandrescu:
>> extraneous arguments passed to writef will be ignored, not printed
>> with default formatting.
> 
> That sounds bad: => "Errors should never pass silently." It's better
> to raise a compilation error. (And if that's not possible, then an
> exception at run-time. But a compilation error is much better).

If it were an error, I wouldn't let it go. A good use case is string tables - a formatted message may or may not use all of the available information.

Andrei
April 20, 2009
Andrei Alexandrescu:
> If it were an error, I wouldn't let it go.

It's an error. It will lead to troubles.

Bye,
bearophile
April 20, 2009
Reply to bearophile,

> Andrei Alexandrescu:
> 
>> If it were an error, I wouldn't let it go.
>> 
> It's an error. It will lead to troubles.
> 
> Bye,
> bearophile

Then there need to be a way for the format string to use an argument without generating output for it because as Andrei is saying, there are real world cases where not using all the args is *normal* and not an error.

One option would be to not throw an error if the format string uses indexing formats (e.i. out of order formatting)


April 20, 2009
bearophile wrote:
> Andrei Alexandrescu:
>> If it were an error, I wouldn't let it go.
> 
> It's an error. It will lead to troubles.

Well at most you could say it's error-prone, something that is easier to argue. The problem is that forcing it into an error makes quite a number of valid uses impossible. An example is a logging application that provides you a number of pieces of information (date, time, message, etc.) and you get to specify how they should be formatted. Oftentimes you'd choose to ignore some data.

Andrei
April 20, 2009
BCS wrote:
> Reply to bearophile,
> 
>> Andrei Alexandrescu:
>>
>>> If it were an error, I wouldn't let it go.
>>>
>> It's an error. It will lead to troubles.
>>
>> Bye,
>> bearophile
> 
> Then there need to be a way for the format string to use an argument without generating output for it because as Andrei is saying, there are real world cases where not using all the args is *normal* and not an error.
> 
> One option would be to not throw an error if the format string uses indexing formats (e.i. out of order formatting)

Yah, that's an option I considered. Maybe it's the best way to go.

Andrei
April 20, 2009
"bearophile" <bearophileHUGS@lycos.com> wrote in message news:gsipn1$1bng$1@digitalmars.com...
> Andrei Alexandrescu:
>> If it were an error, I wouldn't let it go.
>
> It's an error. It will lead to troubles.
>

Sometimes it is an error, but there are times when it isn't:

Suppose you're writing a reporting module for an employee database:

---------------------
ID: 3234
Last: Doe
First: John
Phone: 555-5555
Zip: 90210

ID: 7642
Last: Smith
Etc...
---------------------

And you want the admins to be able to define their own reports:

---------------------
Privileged Report:
For Each Person: "ID #{ID}\nName: {First} {Last}\nPhone: {Phone}\nZip:{Zip}"

Unprivileged Report:
For Each Person: "Name: {Last}, {First}\nContact Info Classified"

Call List In Psuedo-Japanese:
For Each Person Where Name="Smith": "SmithSan {LoopIndex}'s DenwaBango:
{Phone}"
---------------------

So then the report creation code:

---------------------
foreach(int i, Person p; people.subset(customReport.whereClause))
    writefln(customReport.formatStr, i, p.id, p.first, p.last, p.phone,
p.zip);
---------------------

That would be very difficult/limiting if every arg had to be used in the format string.

(Incidentally, this example also demonstrates why I consider C#/Tango-style string formatting superior to C/Phobos-style)


April 20, 2009
"Andrei Alexandrescu" <SeeWebsiteForEmail@erdani.org> wrote in message news:gsiqdr$1csj$2@digitalmars.com...
> BCS wrote:
>> Reply to bearophile,
>>
>>> Andrei Alexandrescu:
>>>
>>>> If it were an error, I wouldn't let it go.
>>>>
>>> It's an error. It will lead to troubles.
>>>
>>> Bye,
>>> bearophile
>>
>> Then there need to be a way for the format string to use an argument without generating output for it because as Andrei is saying, there are real world cases where not using all the args is *normal* and not an error.
>>
>> One option would be to not throw an error if the format string uses indexing formats (e.i. out of order formatting)
>
> Yah, that's an option I considered. Maybe it's the best way to go.
>

That would be far too clumbsy, unless you made it into two separate functions.

For instance (psuedocode):
auto userInput = getUserInput()
// userInput now contains "{Name} at {Address}", zip deliberately ignored
writefln(userInput, name, address, zip); // They're used in-order, but there
shouldn't be an error