December 07, 2018
On Fri, Dec 07, 2018 at 01:46:05PM -0500, Steven Schveighoffer via Digitalmars-d wrote: [...]
> 	text(iq"CODETEMPLATE
> 		void ${funcName}(${funcParams.formatted!"%-(%s, %)"}) {
> 			${generateBoilerplate}
> 			for (i; 0 .. ${numIter})
> 			{
> 				${generateFuncBody}
> 			}
> 		}
> 	CODETEMPLATE");
> 
> Oh, and it requires zero library support. It just works, as if you called it with the parameters in the right place.

The irony is that formatted!"%-%(s, %)" is essentially std.format wrapped in nice clothes, the very thing which we're trying to replace with string interpolation, and the very example of my point, which is that (standard) string interpolation syntax is limited in what it can express before you have to resort to inline code. If we didn't have std.format, you'd have to come up with various helper functions for formatting stuff, which is essentially an escape hatch from the simplistic syntax of string interpolation.  Without the std.format DSL, the only thing we have left is "string with embedded code snippets".

Of course, we could extend the string interpolation syntax with shorthands for common formatting operations, like array formatting, width/precision specifiers, etc.. But then you end up reinventing the std.format DSL (perhaps with a different syntax, which may or may not be nicer).


> With:
> 
> alias argf = formatted!("%-(%s, %)";
> 
> then the function declaration becomes:
> 		void ${funcName}(${funcParams.argf}) {
[...]

Again, the irony is that we're depending on std.format for the formatted!... template.  So why go through the trouble of implementing string interpolation instead of just using std.format to begin with?

Now, mind you, I've nothing against string interpolation, in the language or as a library.  All I'm saying is that having a DSL does make certain things easier to express, though the tradeoff is that you have to learn (possibly obscure-looking) new syntax.  Dispensing with a complex DSL leaves you with convenient basic formatting, but when you need something more than basic formatting, you have to drop down to code.

//

What would be potentially awesome, is if we take the best of both worlds and combine them into a unified DSL that is both powerful (e.g. with concise formatting capabilities like std.format) and readable (by allowing in-place variable names). Then you could write something like this:

	int idx = 20;
	string varname = "myMatrix";
	float[][] data = [
		[ PI, 1, 0 ],
		[ -1, -PI, 0 ],
		[ 0, 0, -1 ]
	];
	auto s = formatNG!("Matrix #0x%{idx}02X '%{varname}s' contains:\n"~
			   "%{data}(\t[ %(%5.2f %) ]%|\n%)");

and it would output:

	Matrix #0x14 'myMatrix' contains:
	[  3.14  1.00  0.00 ]
	[ -1.00 -3.14  0.00 ]
	[  0.00  0.00 -1.00 ]

This would be another application for passing function context as a template parameter.  Once we have that in the language, the implementation of formatNG could potentially look something like this:

	template formatNG(string fmt, context = __traits(getContext))
	{
		...
		enum varName = ...;
		result ~= formatItem(mixin("context." ~ varName));
		...
	}

where the default template argument fetches the caller's context by default.


T

-- 
Do not reason with the unreasonable; you lose by definition.
December 07, 2018
On Friday, 7 December 2018 at 17:11:35 UTC, Atila Neves wrote:
> Every language change is a cost, and therefore should justify its inclusion. I personally don't think that it is in this case just to make a niche use case slightly easier, and this coming from someone from that niche!

Think about `foreach`, `foreach_reverse`, UFCS, WYSIWYG strings, and `switch`. These are all just so-called "niche cases". When you strip out all of the syntax "niches" from a language, you are more or less left with assembly. Hell, assembly itself is just sugar over pure machine code! So with this attitude, why not ditch D and program in machine language?

It's the same case for string interpolation. It *is* possible to live without it, but it is just damn nice when you have it.

---

As a side note, Many people have brought up some very good points, but the conversation looks like it is now starting to stall. I think we should create a DIP template at this point, just to have a place to throw out ideas, not committing to anything yet. Then, if we decide to actually go through with the DIP, we already have all the brainstorming done and in one place. Would someone else (more experienced) like to start the DIP, or should I?
December 07, 2018
On Friday, 7 December 2018 at 19:52:41 UTC, o wrote:
>Would someone else (more experienced) like to start the
> DIP, or should I?

If I have spare time I don't mind starting one. However if you really wanted this, you need start writing it yourself, and post it on the fourms for assistance and feedback. I am pretty sure other people here don't mind helping you writing the dip.

"Be the change that you wanted to see in the world".


-Alex
December 07, 2018
On 12/7/18 2:52 PM, H. S. Teoh wrote:
> On Fri, Dec 07, 2018 at 01:46:05PM -0500, Steven Schveighoffer via Digitalmars-d wrote:
> [...]
>> 	text(iq"CODETEMPLATE
>> 		void ${funcName}(${funcParams.formatted!"%-(%s, %)"}) {
>> 			${generateBoilerplate}
>> 			for (i; 0 .. ${numIter})
>> 			{
>> 				${generateFuncBody}
>> 			}
>> 		}
>> 	CODETEMPLATE");
>>
>> Oh, and it requires zero library support. It just works, as if you
>> called it with the parameters in the right place.
> 
> The irony is that formatted!"%-%(s, %)" is essentially std.format
> wrapped in nice clothes, the very thing which we're trying to replace
> with string interpolation, and the very example of my point, which is
> that (standard) string interpolation syntax is limited in what it can
> express before you have to resort to inline code.

My vision of formatted would be simply a pairing of a format specifier with a value. It would be up to the function to interpret that (i.e. text, or inlineformat or whatever you like).

But the point is you are coupling the format with the value in the same place. Which is the idea behind the "named parameters" that you have.

I don't want the language to do any sort of formatting at all. That's a library feature. We just need the interpolation feature to give us a nicer way to call it.

-Steve
December 07, 2018
On Fri, Dec 07, 2018 at 07:52:41PM +0000, o via Digitalmars-d wrote:
> On Friday, 7 December 2018 at 17:11:35 UTC, Atila Neves wrote:
> > Every language change is a cost, and therefore should justify its inclusion. I personally don't think that it is in this case just to make a niche use case slightly easier, and this coming from someone from that niche!
> 
> Think about `foreach`, `foreach_reverse`, UFCS, WYSIWYG strings, and `switch`. These are all just so-called "niche cases". When you strip out all of the syntax "niches" from a language, you are more or less left with assembly. Hell, assembly itself is just sugar over pure machine code! So with this attitude, why not ditch D and program in machine language?

I think the point isn't to throw out all "niche" uses, but to consider the cost of a new feature *relative to the current state of the language*.  It's clear that we want certain nice features and abstractions that would allow us to not have to write assembly directly. But what is less often recognized / acknowledged is that there's also only a limited amount of "design space" available for you to put features into, so to speak.  Furthermore, a good chunk of this "language real estate" is already occupied by existing language features, so any additional features needs to be carefully weighed against what's currently there, in order not to "run out of design space" and start incurring technical debt.

Well actually, to be more precise, *every* feature comes with a cost (complexity, syntax, increase in learning curve, etc.), and the cost of each additional feature compounds with the total cost of current features (e.g., unexpected/undesired interactions with existing features).  There's only a finite number of features you can add before the cost begins to outweigh the benefits (too many features to learn / remember, too many unexpected interactions between combinations of features, too complex to implement in a straightforward way, resulting in implementation bugs, etc.).  As the number of features grow, the cost of adding even a seemingly-trivial feature also grows.  It doesn't mean we should never add new features, but it needs to offer substantial benefits that outweigh the cost of adding (and maintaining!) it.

It would be very nice if we could just throw everything and the kitchen
sink into the language, but it would end up being a monster of a
language (like C++ (j/k :-P)), unwieldy and overly complex.


[...]
> As a side note, Many people have brought up some very good points, but the conversation looks like it is now starting to stall. I think we should create a DIP template at this point, just to have a place to throw out ideas, not committing to anything yet. Then, if we decide to actually go through with the DIP, we already have all the brainstorming done and in one place. Would someone else (more experienced) like to start the DIP, or should I?

If you have the motivation right now, I think you should just go ahead and draft it up.  The rest of us can help polish it, if need be.  The worst scenario is if the person most motivated to do it doesn't do it, then the rest, who are not as motivated, never get around to it. Then nothing happens and we end up back in square one.


T

-- 
"How are you doing?" "Doing what?"
December 07, 2018
On Friday, 7 December 2018 at 18:46:05 UTC, Steven Schveighoffer wrote:
> But just for fun, let's compare to string interpolation strawman:
>
> 	text(iq"CODETEMPLATE
> 		void ${funcName}(${funcParams.formatted!"%-(%s, %)"}) {
> 			${generateBoilerplate}
> 			for (i; 0 .. ${numIter})
> 			{
> 				${generateFuncBody}
> 			}
> 		}
> 	CODETEMPLATE");
>
> Oh, and it requires zero library support. It just works, as if you called it with the parameters in the right place.
>
> With:
>
> alias argf = formatted!("%-(%s, %)";
>
> then the function declaration becomes:
> 		void ${funcName}(${funcParams.argf}) {
>
> -Steve

This is just plain awesome. I fail to see how anybody can be against this. The more so when you consider it only requires a small change to the frontend.

I especially like the formatted alias. It just keeps getting better.
December 07, 2018
On Fri, Dec 07, 2018 at 03:13:09PM -0500, Steven Schveighoffer via Digitalmars-d wrote: [...]
> My vision of formatted would be simply a pairing of a format specifier with a value. It would be up to the function to interpret that (i.e. text, or inlineformat or whatever you like).
> 
> But the point is you are coupling the format with the value in the same place. Which is the idea behind the "named parameters" that you have.
> 
> I don't want the language to do any sort of formatting at all. That's a library feature. We just need the interpolation feature to give us a nicer way to call it.
[...]

I see.  So that means what we really want is for the language to translate interpolated strings into tuples that can then be processed by library code. In other words, it's not really an interpolated string anymore, it's a kind of "tuple literal" with convenient syntax. It has general applicability, and can be used for all sorts of interesting things beyond just interpolated strings.  Like your database query example.  In fact, it can even form the basis for implementing my named parameters idea.  Once we have it in tuple form, it can be used for all sorts of things.  (Which makes me wonder if we can even make it a replacement for std.meta.AliasSeq ...) It would be an enabler of cool new D idioms, rather than mere syntactic sugar for a "niche" use case.

It also has limited surface area for troublesome / unwanted interactions.  Implementing the scope-as-template-argument idea I proposed would be a lot more dangerous, because it opens up the possibility of innocent-looking function calls to access and modify local variables that are not explicitly passed to it, thus breaking function encapsulation in a pretty evil way.  Standardizing the syntax in the language, where any accessed local symbols are clearly obvious in the source representation, eliminates this possibility.

I think we need to sell it to W&A from this angle. :-D  This is a lot more convincing than "PHP-style interpolated strings would be nice, can we haz it plz, kthxbye".


T

-- 
This is not a sentence.
December 07, 2018
On Friday, 7 December 2018 at 20:59:51 UTC, H. S. Teoh wrote:
> [...]

Yes to everything you just said :)
December 07, 2018
On Friday, 7 December 2018 at 20:12:17 UTC, 12345swordy wrote:
> If I have spare time I don't mind starting one. However if you really wanted this, you need start writing it yourself, and post it on the fourms for assistance and feedback. I am pretty sure other people here don't mind helping you writing the dip.
>
> "Be the change that you wanted to see in the world".
>
>
> -Alex

I started a very rough draft of the DIP (https://github.com/jash11/DIPs/blob/master/Drafts/1NNN-JSH.md).

Everyone who is interested: please take a look and create a PR with any additions. I am completely new to the whole DIP process, so I would greatly appreciate all help and support with the whole process.

Jonathan Marler - If it is okay with you, could you write a little bit about your implementation in the "Description" section?
December 07, 2018
On Friday, 7 December 2018 at 20:59:51 UTC, H. S. Teoh wrote:
> I see.  So that means what we really want is for the language to translate interpolated strings into tuples that can then be processed by library code. In other words, it's not really an interpolated string anymore, it's a kind of "tuple literal" with convenient syntax. It has general applicability, and can be used for all sorts of interesting things beyond just interpolated strings.  Like your database query example.  In fact, it can even form the basis for implementing my named parameters idea.  Once we have it in tuple form, it can be used for all sorts of things.  (Which makes me wonder if we can even make it a replacement for std.meta.AliasSeq ...) It would be an enabler of cool new D idioms, rather than mere syntactic sugar for a "niche" use case.
>
> T

This is phrased **perfectly**. Would you mind adding it to the DIP (https://github.com/jash11/DIPs/blob/master/Drafts/1NNN-JSH.md)? It would be a great addition. Thanks so much!