www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How about appender.put() with var args?

reply =?UTF-8?B?Ik3DoXJjaW8=?= Martins" <marcioapm gmail.com> writes:
Hi!

I use Appender a lot, and find it ugly to write this all the time 
to efficiently construct strings:

app.put("foo");
app.put(var);
app.put("bar");

How about this instead?

app.put("foo", var, "bar");

This would be consistent with the writeln interface, and it could 
also reduce the syntax overhead of using appenders vs string 
concats.

Was this overlooked or is there some issue I am not seeing? :)

Cheers,
-M
Apr 15 2015
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 4/15/15 3:09 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" 
<marcioapm gmail.com>\"" wrote:
 Hi!

 I use Appender a lot, and find it ugly to write this all the time to
 efficiently construct strings:

 app.put("foo");
 app.put(var);
 app.put("bar");

 How about this instead?

 app.put("foo", var, "bar");

 This would be consistent with the writeln interface, and it could also
 reduce the syntax overhead of using appenders vs string concats.

 Was this overlooked or is there some issue I am not seeing? :)

 Cheers,
 -M
What about: import std.format; app.formattedWrite("foo%sbar", var); -Steve
Apr 15 2015
parent reply =?UTF-8?B?Ik3DoXJjaW8=?= Martins" <marcioapm gmail.com> writes:
On Wednesday, 15 April 2015 at 19:16:55 UTC, Steven Schveighoffer 
wrote:
 On 4/15/15 3:09 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" 
 <marcioapm gmail.com>\"" wrote:
 Hi!

 I use Appender a lot, and find it ugly to write this all the 
 time to
 efficiently construct strings:

 app.put("foo");
 app.put(var);
 app.put("bar");

 How about this instead?

 app.put("foo", var, "bar");

 This would be consistent with the writeln interface, and it 
 could also
 reduce the syntax overhead of using appenders vs string 
 concats.

 Was this overlooked or is there some issue I am not seeing? :)

 Cheers,
 -M
What about: import std.format; app.formattedWrite("foo%sbar", var); -Steve
Well, but wouldn't that incur the cost of parsing the format string, for no benefit?
Apr 15 2015
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 4/15/15 4:34 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" 
<marcioapm gmail.com>\"" wrote:
 On Wednesday, 15 April 2015 at 19:16:55 UTC, Steven Schveighoffer wrote:
 What about:

 import std.format;
 app.formattedWrite("foo%sbar", var);
Well, but wouldn't that incur the cost of parsing the format string, for no benefit?
The benefit is, you are not limited to strings :P But yeah, if it's just strings, you have not much benefit. However, I don't know what the cost is for parsing compared to the rest, it may not be too significant. I like Ali's idea, make it a general purpose "putAll" primitive, goes right in std.range.primitives. -Steve
Apr 15 2015
prev sibling next sibling parent reply Justin Whear <justin economicmodeling.com> writes:
Appender will take a range, so you can also do:
  app.put(["foo", var, "bar"]);
 
or
  app.put(chain("foo", var, "bar"));

But yes, a variadic put would be convenient so long as it wasn't 
ambiguous in some way.
Apr 15 2015
parent reply =?UTF-8?B?Ik3DoXJjaW8=?= Martins" <marcioapm gmail.com> writes:
On Wednesday, 15 April 2015 at 19:41:13 UTC, Justin Whear wrote:
 Appender will take a range, so you can also do:
   app.put(["foo", var, "bar"]);
 
 or
   app.put(chain("foo", var, "bar"));

 But yes, a variadic put would be convenient so long as it wasn't
 ambiguous in some way.
I guess chain could work in some cases, and are not that bad on the aesthetic side, I supposed. However having to include std.range just for that, and more importantly, all parameters having to be the same type, as opposed to just being "appendable". Creating an array inline is also not an option as I generally don't like to trade aesthetics <=> efficiency.
Apr 15 2015
parent reply "Nick Treleaven" <ntrel-pub mybtinternet.com> writes:
On Wednesday, 15 April 2015 at 20:40:04 UTC, Márcio Martins wrote:
 I guess chain could work in some cases, and are not that bad on 
 the aesthetic side, I supposed. However having to include 
 std.range just for that, and more importantly, all parameters 
 having to be the same type, as opposed to just being 
 "appendable".

 Creating an array inline is also not an option as I generally 
 don't like to trade aesthetics <=> efficiency.
I think this works: import std.range : only; app.put(only("foo", var, "bar"));
Apr 16 2015
parent Nick Treleaven <ntrel-pub mybtinternet.com> writes:
On 16/04/2015 18:25, Nick Treleaven wrote:
 I think this works:

 import std.range : only;
 app.put(only("foo", var, "bar"));
OK, that doesn't work, and an array doesn't either (which was my assumption): app.put(["foo", var, "bar"]); // NG If it had, I thought only might be more efficient than chain, but I could be wrong.
Apr 17 2015
prev sibling next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 04/15/2015 12:09 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" 
<marcioapm gmail.com>\"" wrote:
 Hi!

 I use Appender a lot, and find it ugly to write this all the time to
 efficiently construct strings:

 app.put("foo");
 app.put(var);
 app.put("bar");

 How about this instead?

 app.put("foo", var, "bar");
Agreed. If a different name like putAll() is acceptable: void putAll(A, T...)(A a, T items) { foreach (item; items){ a.put(item); } } // ... app.putAll("foo", var, "bar"); Ali
Apr 15 2015
next sibling parent =?UTF-8?B?Ik3DoXJjaW8=?= Martins" <marcioapm gmail.com> writes:
On Wednesday, 15 April 2015 at 20:44:07 UTC, Ali Çehreli wrote:
 On 04/15/2015 12:09 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" 
 <marcioapm gmail.com>\"" wrote:
 Hi!

 I use Appender a lot, and find it ugly to write this all the 
 time to
 efficiently construct strings:

 app.put("foo");
 app.put(var);
 app.put("bar");

 How about this instead?

 app.put("foo", var, "bar");
Agreed. If a different name like putAll() is acceptable: void putAll(A, T...)(A a, T items) { foreach (item; items){ a.put(item); } } // ... app.putAll("foo", var, "bar"); Ali
This is great! I would still call it just put(), close to writeln()'s interface. It shouldn't break any existing and compiling code, right?
Apr 15 2015
prev sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Wednesday, 15 April 2015 at 20:44:07 UTC, Ali Çehreli wrote:
 On 04/15/2015 12:09 PM, "=?UTF-8?B?Ik3DoXJjaW8=?= Martins\" 
 <marcioapm gmail.com>\"" wrote:
 Hi!

 I use Appender a lot, and find it ugly to write this all the 
 time to
 efficiently construct strings:

 app.put("foo");
 app.put(var);
 app.put("bar");

 How about this instead?

 app.put("foo", var, "bar");
Agreed. If a different name like putAll() is acceptable: void putAll(A, T...)(A a, T items) { foreach (item; items){ a.put(item); } } // ... app.putAll("foo", var, "bar");
A hypothetical variadic put method would have the advantage over this in that it could could calculate the total length and preallocate for all arguments in one go.
Apr 16 2015
prev sibling next sibling parent reply "Messenger" <dont shoot.me> writes:
On Wednesday, 15 April 2015 at 19:09:42 UTC, Márcio Martins wrote:
 Hi!

 I use Appender a lot, and find it ugly to write this all the 
 time to efficiently construct strings:

 app.put("foo");
 app.put(var);
 app.put("bar");
Sidetracking a bit, but when I started using Appender I was surprised to see that put didn't return a reference to the Appender itself. Had it done so, you could have chained your put calls very nicely. app.put("foo") .put(var) .put("bar") .put(more) .put("stuff"); You can naturally write a small wrapper function that does this for you, but it still strikes me as odd. Sadly I imagine changing the return type would make the function signature mangle differently, breaking ABI compatibility.
Apr 15 2015
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 4/15/15 4:51 PM, Messenger wrote:
 On Wednesday, 15 April 2015 at 19:09:42 UTC, Márcio Martins wrote:
 Hi!

 I use Appender a lot, and find it ugly to write this all the time to
 efficiently construct strings:

 app.put("foo");
 app.put(var);
 app.put("bar");
Sidetracking a bit, but when I started using Appender I was surprised to see that put didn't return a reference to the Appender itself. Had it done so, you could have chained your put calls very nicely. app.put("foo") .put(var) .put("bar") .put(more) .put("stuff"); You can naturally write a small wrapper function that does this for you, but it still strikes me as odd. Sadly I imagine changing the return type would make the function signature mangle differently, breaking ABI compatibility.
with(app) { put(var); put("bar"); put(more); put("stuff"); } -Steve
Apr 15 2015
next sibling parent "Messenger" <no u.blarp> writes:
On Wednesday, 15 April 2015 at 20:59:25 UTC, Steven Schveighoffer 
wrote:
 with(app)
 {
    put(var);
    put("bar");
    put(more);
    put("stuff");
 }

 -Steve
Awesome.
Apr 15 2015
prev sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 15 April 2015 at 20:59:25 UTC, Steven Schveighoffer 
wrote:
 On 4/15/15 4:51 PM, Messenger wrote:
 On Wednesday, 15 April 2015 at 19:09:42 UTC, Márcio Martins 
 wrote:
 Hi!

 I use Appender a lot, and find it ugly to write this all the 
 time to
 efficiently construct strings:

 app.put("foo");
 app.put(var);
 app.put("bar");
Sidetracking a bit, but when I started using Appender I was surprised to see that put didn't return a reference to the Appender itself. Had it done so, you could have chained your put calls very nicely. app.put("foo") .put(var) .put("bar") .put(more) .put("stuff"); You can naturally write a small wrapper function that does this for you, but it still strikes me as odd. Sadly I imagine changing the return type would make the function signature mangle differently, breaking ABI compatibility.
with(app) { put(var); put("bar"); put(more); put("stuff"); } -Steve
With all the excitement about chaining and ufcs, the with statement is often overlooked.
Apr 16 2015
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/15/15 1:51 PM, Messenger wrote:
 On Wednesday, 15 April 2015 at 19:09:42 UTC, Márcio Martins wrote:
 Hi!

 I use Appender a lot, and find it ugly to write this all the time to
 efficiently construct strings:

 app.put("foo");
 app.put(var);
 app.put("bar");
Sidetracking a bit, but when I started using Appender I was surprised to see that put didn't return a reference to the Appender itself. Had it done so, you could have chained your put calls very nicely. app.put("foo") .put(var) .put("bar") .put(more) .put("stuff"); You can naturally write a small wrapper function that does this for you, but it still strikes me as odd. Sadly I imagine changing the return type would make the function signature mangle differently, breaking ABI compatibility.
Does ~= chain? -- Andrei
Apr 15 2015
parent reply "Messenger" <dont shoot.me> writes:
On Thursday, 16 April 2015 at 03:53:56 UTC, Andrei Alexandrescu 
wrote:
 Sidetracking a bit, but when I started using Appender I was 
 surprised to
 see that put didn't return a reference to the Appender itself. 
 Had it
 done so, you could have chained your put calls very nicely.

 app.put("foo")
    .put(var)
    .put("bar")
    .put(more)
    .put("stuff");

 You can naturally write a small wrapper function that does 
 this for you,
 but it still strikes me as odd. Sadly I imagine changing the 
 return type
 would make the function signature mangle differently, breaking 
 ABI
 compatibility.
Does ~= chain? -- Andrei
I'm not sure I understand. Appender!string app; app ~= "hello" ~= " " ~= "kitty"; --> Error: Cannot modify '" "' Is the order of evaluation not such that this becomes app ~= ("hello" ~= (" " ~= "kitty"))?
Apr 16 2015
parent ketmar <ketmar ketmar.no-ip.org> writes:
On Thu, 16 Apr 2015 21:58:43 +0000, Messenger wrote:

 Appender!string app;
=20
 app ~=3D "hello"
      ~=3D " "
      ~=3D "kitty";
=20
 --> Error: Cannot modify '" "'
=20
 Is the order of evaluation not such that this becomes app ~=3D ("hello" ~=
=3D
 (" " ~=3D "kitty"))?
yes, assign is right associative.=
Apr 16 2015
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Márcio Martins:

 app.put("foo");
 app.put(var);
 app.put("bar");
I'd like put() to accept a lazy range... Bye, bearophile
Apr 16 2015