question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Proposal] Capture names (or full code) of interpolated values if string interpolation is passed in as a FormattableString

See original GitHub issue

This proposal was already answered on CodePlex with “too late for C#6”, but since C#7 is taking input at the moment, I think it is worth mentioning this again.

Problem:

Current design for FormattableString is:

public class FormattableString {
    public string Format { get; }
    public object[] Args { get; }
    // ...
}

Consider two following usages:

// Some future Serilog:
log.Information($"Processed {position} in {elapsedMs:000} ms.");

// Some future Dapper:
connection.Execute($"SELECT * FROM T1 WHERE Id = {id}");

In addition to saving the log string, Serilog saves format values as properties on the log entry object. However with current FormattableString the names of these values (position, elapsedMs) would not be available.

Dapper does not really need the names (it can generate parameters named @p1 and @p2), but proper names can improve readability of SQL traces and general SQL debugging.

And another (weird) use case for capturing names of the provided values:

Argument.NotNull($"{x}"); // doesn't actually need the string at all, but uses arg name/value

Compare this with current:

Argument.NotNull(nameof(x), x); // more verbose, not DRY

Potential solution

Add IReadOnlyList<string> Names { get; } to the FormattableString.

Those could be generated based on anonymous class property name algorithm:

1. $"{x}, {y}"  // Names = "x", "y"
2. $"{x.Y.Z}"   // Names = "Z"
3. $"{x}, {5}"  // Names = "x", null

Or just literally contain passed in code as a string, e.g. $"{x+5}" // Names = "x+5", though in this case something like Snippets would be a better name.

Since each call site will have a fixed set of names/snippets, each list can be cached per call site once and reused between calls. This means that even the names/snippets aren’t used, the performance cost would be minimal.

Pros
  1. Allows frameworks to be more intelligent when generating a new string from FormattableString or recording the parameters somewhere.
  2. Gives some unexpected uses to the FormattableString by making it a light-weight way to pass identifier-named value – e.g. validation.
  3. If code is passed as as string instead of generating a name, this can be used to create an easily cacheable analog of expression trees (by parsing it with Roslyn etc), and various other kinds of ‘magic’ APIs.
Cons
  1. If names are generated using anonymous class algorithm, some of them might be null. This might be unexpected – frameworks can provide fallback, but they have to be careful of those cases.
  2. If full code is passed as a string, analysis has to be careful so that it is not broken by small variations within the code (e.g. as introduced by refactoring).

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Reactions:7
  • Comments:50 (32 by maintainers)

github_iconTop GitHub Comments

12reactions
ashmindcommented, Apr 11, 2016

@gafter The reason is important. The way your original decision was worded strongly discouraged me from providing any Roslyn feedback in the future. I don’t mind the rejection, but why spend my free time doing well-structured proposals to get a single sentence? Which gives me no idea on what I did wrong – or how to avoid wasting your (and my) time again.

I suppose it depends on your situation. If you are overloaded with ideas, then I understand why it doesn’t matter if you lose a few people along the way.

However I’ll still give my two cents on what I would like to see in a proper Roslyn decision:

  1. Why the idea does not work.
  2. Whether it’s rejected from the language or from the team backlog – can other people grab it?
  3. Whether it was discussed by Roslyn team and a link to the meeting notes if so.
9reactions
MadsTorgersencommented, Apr 11, 2016

Fortunately and unfortunately we get more proposals than we can discuss in any depth. Folks on the LDM spend time looking at proposals here on GitHub, and bring up ones that they feel should warrant a discussion. This may be because they agree with the proposal, or feel that it raises a scenario that is worth trying to address, or similar. We call this “championing” a feature. This is our primary filtering mechanism, and it helps us focus our limited time on proposals that have a chance.

I realize how annoying it is to spend time on a proposal and then have it ignored or summarily dismissed. I wish there was a realistic process by which we could formulate a “why not” for every well-worked-out proposal that we do not choose to adopt into the language. Neal closing this issue is the closest we can get - he realizes the issue won’t make it to a discussion, and closes it as a signal to the participants on the thread to help prioritize their efforts.

I’m sorry if this comes off as non-appreciative: it is not! We deeply value the discussions and proposals here, and they have a big influence on where we take the language. This goes for feature proposals, and equally for the many posts pointing out flaws and inconsistencies in proposals - ours and others’. I want to thank everyone who spends time and creative energy here, enriching the discussion and helping drive the languages forward.

If you feel a proposal really deserves our attention and isn’t getting it, I recommend submitting it on UserVoice as well:

https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/category/30931-languages-c https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/category/30933-languages-visual-basic

Whereas the feedback here on GitHub is rich on technical commentary and insights, UserVoice has the crucial benefit of allowing voting. It also tends to reach a more representative set of developers. Top UserVoice suggestions are sure to grab our attention, whether or not we are able to do something about them. In this way, the two forums supplement each other well.

Again, thanks for all the great ideas! I love the intensity, quality and volume of discussion, and it breaks my heart that we (the language designers) cannot engage deeply in all of it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Improved interpolated strings - C# 10.0 draft feature ...
This proposal creates a way to use this type safely from native C# code by just writing an interpolated string literal, leaving written...
Read more >
PEP 501 – General purpose string interpolation
PEP 498 makes interpolating values into strings with full access to Python's lexical namespace semantics simpler, but it does so at the cost...
Read more >
Syntax – Page 2 - somewhat abstract
We have now specified that we are using a variable of type `FormattableString`. With this declaration, the compiler changes its behavior and we...
Read more >
Difference between String, FormattableString, IFormattable
A FormattableString consists of the format string which would be passed to string.
Read more >
Intercepting String Interpolation
It takes each interpolated expression value used in the original literal and adds it as a parameter to a SQL command it builds....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found