Thread overview
Orphan format arguments: args[0..1]
Dec 16, 2018
Ali Çehreli
Dec 16, 2018
bauss
Dec 16, 2018
Ali Çehreli
December 15, 2018
This one confused me until I decided to talk to a rubber ducky:

import std.string;

void main() {
    auto s = "%s is a good number".format(42);
}

Fine; it works... Then the string becomes too long and I split it:

    auto s = "%s is a good number but one needs to know" ~
             " what the question exactly was.".format(42);

Now there is a compilation error:

  Orphan format arguments: args[0..1]

What? Is that a bug in format? It can't be because the string should be concatenated by the compiler as a single string, no? No: operator dot has precedence over ~, so format is applied to the second part of the string before the concatenation. Doh! This puzzled me a lot.

Anyway, the solution, once again, is to use parentheses:

    auto s = ("%s is a good number but one needs to know" ~
              " what the question exactly was.").format(42);

Ali
December 16, 2018
On Sunday, 16 December 2018 at 00:34:48 UTC, Ali Çehreli wrote:
> This one confused me until I decided to talk to a rubber ducky:
>
> import std.string;
>
> void main() {
>     auto s = "%s is a good number".format(42);
> }
>
> Fine; it works... Then the string becomes too long and I split it:
>
>     auto s = "%s is a good number but one needs to know" ~
>              " what the question exactly was.".format(42);
>
> Now there is a compilation error:
>
>   Orphan format arguments: args[0..1]
>
> What? Is that a bug in format? It can't be because the string should be concatenated by the compiler as a single string, no? No: operator dot has precedence over ~, so format is applied to the second part of the string before the concatenation. Doh! This puzzled me a lot.
>
> Anyway, the solution, once again, is to use parentheses:
>
>     auto s = ("%s is a good number but one needs to know" ~
>               " what the question exactly was.").format(42);
>
> Ali

The reason it doesn't work in the second example is because it translates to something like this:

auto s = "%s is a good number but one needs to know" ~ ("what the question exactly was.".format(42));

The reason encapsulation the two strings works is because you append the second string to the first before you call format.

Definitely not a bug.
December 16, 2018
On 12/15/18 7:34 PM, Ali Çehreli wrote:
> This one confused me until I decided to talk to a rubber ducky:
> 
> import std.string;
> 
> void main() {
>      auto s = "%s is a good number".format(42);
> }
> 
> Fine; it works... Then the string becomes too long and I split it:
> 
>      auto s = "%s is a good number but one needs to know" ~
>               " what the question exactly was.".format(42);
> 
> Now there is a compilation error:
> 
>    Orphan format arguments: args[0..1]

Hm... maybe a runtime error? I didn't think the compiler knows to complain about this.

> 
> What? Is that a bug in format? It can't be because the string should be concatenated by the compiler as a single string, no? No: operator dot has precedence over ~, so format is applied to the second part of the string before the concatenation. Doh! This puzzled me a lot.

Yes, in fact that is kind of a difference from previous "auto-concatenation" if you just put whitespace between the strings.

-Steve
December 16, 2018
On 12/16/2018 12:00 PM, Steven Schveighoffer wrote:

>> Now there is a compilation error:
>>
>>    Orphan format arguments: args[0..1]
>
> Hm... maybe a runtime error? I didn't think the compiler knows to
> complain about this.

Sorry, it was a runtime error. (I was seeing compile time because of the following.)

> Yes, in fact that is kind of a difference from previous
> "auto-concatenation" if you just put whitespace between the strings.

Yes. The reason for my confusion was, since the former is deprecated, I assumed the following two would exactly be the same:

  "hello" "world"
  "hello" ~ "world"

Whether they are the same depends on code around them; hence my post. :)

> -Steve

Ali