dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.04k stars 4.03k forks source link

Support := syntax as an alternative to var #16442

Closed corliss closed 6 years ago

corliss commented 7 years ago

The title says it all...

HaloFour commented 7 years ago

I know that keywords over symbols is a tenet of C# design. However, perhaps it is worth questioning that in this case.

No, I don't think it is. Sure, if you're more familiar with Go then Go-syntax would be easier for you to digest. But would you argue that Go should adopt C# syntax so that Go can be adopted easier by C# programmers? No, you wouldn't. C# shouldn't try to syntactically be every other language.

And I personally find the Go syntax pretty ugly. A simple and obvious declaration has been replaced by a jumble of punctuation. It also removes the one most important element from focus, namely that this is a variable declaration.

HaloFour commented 7 years ago

You are allowed to have an opinion, which is why you can create proposals here. But I am also allowed to have an opinion, which is why I can comment on it. 😀

HaloFour commented 7 years ago

Geez, no need to close the issue. I'm just posting my opinion. It's not up to me whether such a feature would be implemented or not.

CyrusNajmabadi commented 7 years ago

Reopening. There is no reason for us to not consider this.

--

Can we please bit an end to the back/forth about this and keep all future conversation about the appropriateness of this feature to the C# language. :) Thanks!

CyrusNajmabadi commented 7 years ago

Personally, while i'm a fan of brevity, this PR does have some concerns for me.

First, having more ways to do things is not really a virtue in my mind. At least, not when there aren't huge benefits to the proposal. Here, i'm seeing only minor benefits.

Second, this would dramatically affect the IDE experience. Effective any identifier following a statement could be the start of a declaration. We would ahve to massively curtail what intellisense was allowed to do here because we'd never know if you were declaring a new variable, or referencing an existing symbol. That alone would make me very cautious. We've had similar issues int he past with lambdas. But there the brevity was so important (and we could effectively detect the situations where it would happen) that we accepted it. Here, neither of those apply.

CyrusNajmabadi commented 7 years ago

However, even if intellisense optimistically assumed that it was an existing symbol, e.g. an autocomplete suggestion, that might be ok. Can you think of an intellisense example that would confuse the user?

It would definitely be a problem. Consider something as simple as this:

i<space_key>

in this case, the user might be wanting to complete out to int<space>, or they may want to write i := ...

Because this point is both a declaration and reference point we would have to not allow intellisense to be committed automatically here. That would def degrade the experience from today when users can expect that this is only a reference location, and thus they can type a portion of the intellisense item, hit a character (like space or dot) and have the right item auto-commit.

CyrusNajmabadi commented 7 years ago

That would only occur when the entire variable name is the prefix of an existing symbol.

No. it also happens if the name if a sub-portoin of an existing symbol. Or if the existing name camel-case matches. And, in the future, it will happen with our better fuzzy-matching logic that detects when you might be mispelling something.

Also, this is exceedingly common. Names are heavily reused by people. For example:

var list var button var token

etc. etc. these names are commonly equal to (case-insensitively) or part of an existing larger name in scope.

If the auto-commit were allowed, Ctrl+Z is always available to undo the auto-commit.

And this would be a pretty terrible experience. Imagine a person that only wants to use :=. Effectively, much of the time they'd be having to ctrl-z what the IDE was doing. That's not a good experience.

CyrusNajmabadi commented 7 years ago

Are there other cases in the product at present where the user needs to undo this way?

Basically, no. And that's purposeful. As we've designed the language, we've taken the editing and IDE scenarios into account. One of the few places we have this is with lambdas. After all, when you type:

Foo(c, then 'c' might be the start of a expression that references existing symbols, or it might be the start of a lambda like so Foo(c => c.Age > 21).

However, we do work to at least detect this by seeing if Foo at least binds, and if it takes an argument that is a delegate. In that case, we do change intellisense behavior. However, importantly, we do not regress the common case here. We only tweak behavior when we have the data to strongly indicate the user is likely typing a lambda. No such heuristic exists with your proposal. literally the start of any statement could now be an expression that is referencing symbols, or it could be the declaration of a variable. There is no way to tell. There is no surrounding context we can use to limit things.

sharwell commented 7 years ago

@CyrusNajmabadi @corliss I have a particularly relevant demo of what IntelliSense would be able to do in such a scenario as part of this video (starting at the 5 minute mark and going to the end). My experience found the following:

  1. The IntelliSense experience is only slightly less efficient on the left edge once you are used to it (you have to press tab to code complete a reference in that location, but that could probably be expanded so certain other non-identifier characters which can't be part of a variable declaration also trigger reference completion)
  2. It's pretty easy for a user to adapt
  3. It's hard to get this right. Suggestion mode in Visual Studio doesn't work exactly like the one seen in the video, and the differences would lead to some notable inefficiencies if they weren't corrected. Little bugs have made their way into the existing suggestion mode over time and had to be corrected; this feature would make them both more common and more obvious.

That said, the following come to mind as well:

  1. We would only be saving 2 characters of typing (3 if you count the space after var) for type inference scenarios
  2. Users tend to dislike change, especially when it means more work to do the same thing. This really applies to users who aren't using :=
CyrusNajmabadi commented 7 years ago

(First, i did watch your video. Don't want you to think i'm jumping ahead or anything :))

The part i'm skeptical about is '2'.

We have a lot of users, and we get immediate complaints when things change and muscle memory is broken. The model you've presented is very similar to what we did for lambdas. i.e. the item is 'soft selected', and only the <tab> commit character forces commit. However, this would be taking that model and enforcing it in a super common location which feels like it would really step back the experience.

Note: i am agreeing this is a possible mitigation. However, as i stated originally, it seems like a large take-back for a feature of very marginal benefit.

sharwell commented 7 years ago

@CyrusNajmabadi To be clear, what I meant is it's easy (predictable) for a user to know where to expect the suggestion mode to appear, even if they aren't thinking about it. But it does appear a lot.

On the issue as a whole, I would say the approach led to a dramatic productivity improvement for developers working in Go, but not so much that it made the editor experience as a whole more productive compared to C#. The IntelliSense drawback is very real, very relevant, and probably a primary motivating factor for staying away from this syntax. It's just not quite so severe as one would guess at first look.

CyrusNajmabadi commented 7 years ago

C# has already made one-line functions terse with => expression syntax, and this proposal will hopefully make the most common type of function - medium sized ones - easier to read.

I'm also skeptical about this point. One of the benefits of a keyword-oriented language approach is that is scans incredibly simply from a left-to-right perspective. That's a reason i actually dislike C# with some of our syntax (since we share too much left-side syntax with things like modifiers). 'var' actually improved readability of C# quite a bit as one had clear syntax indicating a variable was being introduced.

Brevity and terseness of expressoins/statements come with varying levels of tradeoffs. I'm very familiar with languages like go/swift/f#/etc. and they all attempt to strike a balance here between these factors. C# has chosen a balance that has err'ed on not overly preferring brevity at all cost. You can see that with our list-comprehensions and many other language features. Indeed, this has been so ingrained, that we have nearly no cases where this left-edge ambiguity exists and we have pushed against it unless we've felt the value is super high. Lambdas warranted it. But a '2-4 character saving' for variables likely does not.

CyrusNajmabadi commented 7 years ago

may be easier for the compiler to scan

I was speaking solely from the perspective of user readability. The initial token tells you immediatley what you're looking at. You don't need to go forward to see "is this 'foo' a declaration or a reference?"

CyrusNajmabadi commented 7 years ago

but I'd say that foo := bar is hard to argue with in terms of readability.

It's very easy to argue. The argument is simple, one form tells you what it is on the very first token, and the very first piece of non-whitespace. The other form forces you to look past the first token (and possibly past some long sequence of tuple-variables) to determine what it is you're looking at. :)

CyrusNajmabadi commented 7 years ago

and the operator itself is mostly unspoken in the mind.

The operator must be understood to know what's going on. In both cases you're creating a variable with a name and assigning a value to it.

HaloFour commented 7 years ago

The operator is of utmost important in the following:

class C {
    int foo;
    public void M1() {
        foo = 123;
    }

    public void M2() {
        foo := 123;
    }
}
sharwell commented 7 years ago

Ignoring existing users' preferences and learned behavior, the main readability case that puts := in C# at a direct disadvantage compared to := in Go is the fact that there would be two common ways to declare a variable with type inference instead of just one. Lack of a type (or var) on the left side of an identifier would no longer mean that the item is a reference. This could get pretty awful, e.g. if one developer on a project prefers (or has long experience with) var while another on the same project prefers :=.

I find that its easier to scan for the "meaning" of things on the left side than the right, since the left edge is the only location in C# where one can reasonably expect to find consistent vertical alignment. The gofmt tool provides this expectation in more places in Go code, with an emphasis on ensuring the := is readable.

HaloFour commented 7 years ago

I disagree with that assertion. I don't see how var x = 123; is any harder to parse than x := 123;. If anything the latter makes you take pause to ensure that what you're looking at is a declaration vs. an assignment. I have no problem mentally parsing and understanding the current implicit declaration form. I know right away the most important aspect of the statement; that it is a declaration of a new variable.

HaloFour commented 7 years ago

We already have two common ways

Not "with type inference".

CyrusNajmabadi commented 7 years ago

and the former is just understood to be an archaism.

This is not true.

CyrusNajmabadi commented 7 years ago

I assume you mean the cases where you need to explicitly state the type

Yes. It is not considered an archaism. Full stop. Indeed, there are full teams (like the .net team and the roslyn compiler team) that have this as an actual rule they are required to follow.

CyrusNajmabadi commented 7 years ago

Why are we even arguing about this then?

You filed the request. I'm simply giving you my perspective as one of the language designers about how i feel about the proposal and the specific things i'm looking at when i judge it.

iam3yal commented 7 years ago

@corliss

To avoid understanding that the form "x = y" has a special quality that has made it the core representation of mathematics

Can you elaborate on this special quality? all I see is an assignment in the context of some programming languages which is actually an equality in mathematics but what makes it special?

CyrusNajmabadi commented 7 years ago

is to miss the point.

The point is not being missed. Trust me, the designers here are well aware of the wealth of syntactic choices we have, and hte designs taken by many other languages. What i'm trying to explain is that there are many concerns on the table that we consider on top of that and we have to evaluate the proposal in that context.

For example, we must take into account the fact that C# is not being sprung into the world as a V1 language. Any language changes must address how those changes fit into the existing language and the wealth of code that already exists. Any feature that provides an equivalent way to do something must justify that it provides enough benefit to warrant the potential bifurcation of syntax.

Another, common, way to think about is this: All language features start out with a huge net negative score. That's the cost they have to the entire ecosystem for people to learn it. For the tools to adopt it. To deal with the confusion of having multiple ways to do things. Etc. etc. In order to do a feature the value has to be so much that it outweighs that net negative scope. Right now, the only benefit is the perceived slightly better readability. That's incredibly marginal and really hard to justify.

iam3yal commented 7 years ago

@corliss Yeah.. interesting, indeed.

ghost commented 7 years ago

It's inconsistent with what I would expect of C# syntax

When I see this, and if I knew nothing about it name := 5; My mind would jump to this name = name : 5;

Like how this name += 5; is the same as this name = name + 5;

timopomer commented 7 years ago

imo this is pretty bad. its difficult to spot in code as in c# variable declarations ALWAYS specify the variable name before the name and then one variable type isnt defined that way for some reason

DavidArno commented 7 years ago

I'm going to cast a contrary +1 for this. I actually quite like the syntax. However, I accept that, based on the overwhelming number of -1's and @CyrusNajmabadi's point that it would play havoc with intellisense, it isn't ever going to happen.

I will add though that rather than replacing var, I'd see it as an alternative to let/readonly, but that's a different proposal, I guess. 😸

alrz commented 7 years ago

May we have this in "when heck freezes over" milestone?

iam3yal commented 7 years ago

@DavidArno The syntax is indeed nice but I don't know why people think that this is readable:

y := 1;
x := y;
x += 1;
DavidArno commented 7 years ago

@eyalsk,

I agree, x += 1; makes me cry, filling my eyes with tears, and thus making it hard to read. 😝

dsaf commented 7 years ago

@CyrusNajmabadi

Reopening. There is no reason for us to not consider this.

I assumed there is a limitation to how invasive you are willing to be with the established syntax. Could moving type information to the right side in every C# language construct be realistically considered as well? I've heard it provides many syntactic benefits for both developers and language designers (hence Rust/Scala/Swift/Nemerle all doing it).

const int x = 3;

static int foo (int x, string y) 
{ ... }

vs

const x : int = 3;

static foo (x : int, y : string) : int 
{ ... }

Please let me know if I should open a separate issue for this.

jnm2 commented 7 years ago

@DavidArno

I'm going to cast a contrary +1 for this.

Bet no one saw that coming or anything ;-)

alrz commented 7 years ago

I've heard it provides many syntactic benefits for both developers and language designers

@dsaf So I think JS actually did it right long time ago. No type annotation to be worry about.

dsaf commented 7 years ago

@alrz (not sure if you are joking) whatever was done in JS was driven by lack of time and lack of types. The most promising fix of JS - Typescript - puts optional typing on the right side (wouldn't be surprised to see this in ES8/9). Just consider stopping and seriously considering such syntax for a minute.

CyrusNajmabadi commented 7 years ago

I assumed there is a limitation to how invasive you are willing to be with the established syntax.

True. But I don't think any reasonable proposal should be thrown out immediately without at least discussing and laying out the pros/cons. At the very least, it helps clarify some of the decision making that some LDM members make when considering this sort of thing.

--

I will point out that, in general, we're cautious about adopting new syntax. That's especially true if it's syntax to do the same thing as what we already have. Indeed, in C# we've rarely ever done that. Generally, new syntax comes either from:

  1. New features that are valuable enough and thus must need the new syntax. (i.e. pattern matching).
  2. Existing features that we feel we can simplify, without bifurcation. i.e. allowing => for expression bodied members.
  3. A realization that the existing syntax is truly terrible, and actually interferes with the goals we have for the language. i.e. delegate (c) { return c.Age > 21; } instead of c => c.Age > 21.

We don't take new syntax for existing features "just because" or just if is slightly better than what we have. New syntax really needs to carry it's own weight and truly justify its addition to the language.

In my personal opinion, := doesn't come close. It's only marginally better than what we have, and comes with definite baggage that we'd be concerned about.

--

Could moving type information to the right side in every C# language construct be realistically considered as well?

Sure! But, again, would it have enough value to warrant it. I do want to reiterate though that C# versions are not designed in a vacuum. In other words, we don't design saying "man... if we could do it all over again, here's what we would do". We design given the language as it has evolved so far, and given the literal billions of lines of code out there. Massively upending a core choice the language has made can be incredibly disruptive and would really need to be super valuable to warrant it.

Syntax changes for the sake of syntax changes can rarely justify themselves. Again, AFAICT, we've only done it once. In order for syntax changes to be justified, they really have to enable something amazing, or they must truly and dramatically improve things. In general, that's extremely rare.

CyrusNajmabadi commented 7 years ago

Also, please note that i'm not at all trying to rain on anyone's parade. Man do i love syntax. When we do work on syntax in the LDM we pore over every detail. We nitpick. We bikeshed. We feel the pain intimately when we see the problems with it.

But, i just need to make it clear that C# is not a language that embraces routine syntax change. We want every step of the language to feel like a natural evolution. And we want all that learning and muscle memory, and pattern recognition that happens in your brain, to still be just as relevant today as it was in C# 1. Indeed, C# 1 should look extremely familiar and normal to someone using C# 6. today. Yes, there will be places where things can be dramatically nicer today. But nearly all of it should still feel like it is C#.

The more we lurch around with syntax, the more that C# feels like a target you're always chasing. One that you're never quite sure you can trust or invest in. If we add := we'll have vast swaths of people never using it. And we'll have people who will always be concerned "should i even use this? or are they jsut going to come up with something later (maybe <-) to just replace this in the future?"

--

So, to reiterate: Proposing syntax: great! Thinking and discussing syntax: great! But don't be too disappointed if the way we develop the language means that many/most of the syntax proposals don't happen.

CyrusNajmabadi commented 7 years ago

So, to reiterate: Proposing syntax: great! Thinking and discussing syntax: great! But don't be too disappointed if the way we develop the language means that many/most of the syntax proposals don't happen.

The best way to get syntax changes is to really be able to demonstrate the value, or to attach to new valuable features that warrant addition to the language. We can then judge if there is enough merit. For example, when you have C# 1, you'll see this all over the place:

private readonly int _age;
public int Age
{
    get
    {
        return _age;
    }
}

Even reducing the formatting still gives you:

private readonly int _age;
public int Age { get { return _age; } }

This is (what i like to call) "token salad". The intent of the code is so masked by all the pomp and circumstance of the language. Compare to current versions of C# which can give you either:

private readonly int _age;
public int Age => _age;

or even

public int Age { get; }

That's 8 lines to 1, and that's 16 tokens to 7, and that's 50chars to 23. Here this was just a matter of syntax, but it really pulled it's weight in terms of cleanup and clarity. And, importantly, it felt like a natural evolution of the language. We didn't replace existing properties with something like:

Age := public int

We could have. It's shorter, and uses less tokens. But it would not feel like something that naturally evolved from the existing language. These are very important things to consider with syntax. And they're more important the longer the language has been around.

If i had the chance to do it all over again, much would be different in C#. But we're working on C#7. Not Cyrus#1. :)

DavidArno commented 7 years ago

@CyrusNajmabadi,

But don't be too disappointed if the way we develop the language means that many/most of the syntax proposals don't happen.

As long as the match keyword - with accompanying pattern matching expressions (and ADT's and records of course) - appears in v7.1, I'm sure most of us will forgive the LDM rejecting almost all other syntax change requests 😉

dsaf commented 7 years ago

@CyrusNajmabadi Thanks, your answer should be pinned to homepage or something :).

I wish Microsoft Research had a team developing a research C# clone with this motto, though:

"if we could do it all over again, here's what we would do"

CyrusNajmabadi commented 7 years ago

As long as the match keyword ... appears in v7.1

If it makes you feel better, i'm pretty sure there is near unanimous support for a good, expression based, approach to pattern matching and whatnot. I can't promise anything, and i certainly can't promise a release vehicle. But i can say that it's a prime focus and we're definitely enthusiastic about working on it.

We met yesterday to deal with some of the awfulness that comes about from 'switch', and i think most people felt that life would be so much nicer and we would be able to address so many issues cleanly if we just had a new, focused, syntax for these scenarios that fit far better into the style that so many have adopted for functional/pattern-matching language constructs.

--

My personal hope is that sooner rather than later, we'll be able to put these features back on the table (like ADTs, expression matching, recursive patterns, etc.) and i hope that they'd make it to you in a timely fashion. All these hopes are my own. No promises or anything beyond that :)

iam3yal commented 7 years ago

@CyrusNajmabadi So this is what C# really stands for Cyrus#! 😆

CyrusNajmabadi commented 7 years ago

And i'm still trying to squeeze in the "Naj" (nudge) operator ~> into the language somehow...

CyrusNajmabadi commented 7 years ago

In exactly the same way, if := were implemented, then a choice for i := could appear in the intellisense list. The order doesn't matter, and the user gets to choose whether to accept the default, change it, or temporarily Escape out of intellisense.

You have now broken muscle memory. I want tok<space> to continue completing to token for me. It now would not do that.

What you are describing is precisely what we have for the lambda ambiguity case. However, now you're making teh start of every statement ambiguous. With lambdas we could accept the intellisense pain because the value of hte feature was so high, and because we could limit the places where we would need to do this. With your suggestion we would have to vastly extend this sort of case to now impact the common typing cases.

Or, in other words, our heuristic actually works well for lambdas, as much of the time a person can type a delegate, they will end up writing a lambda. So the degradation isn't so bad. The same is not true for the start of a statement. Massive amounts of stated start with a reference to a symbol or a keyword. You are now making it so that we cannot confidently select and insert those automatically because of hte ambiguity.

I'm not arguing that there's no solution. I'm arguing that the solution is a serious step back in experience, and dramatically will impact muscle memory and user satisfaction moving forward.

--

This will also especially affect users using multiple versions of VS. People do commonly use multiple versions, and they will now have a dramatically different typing experience across versions. That's not something that can be done lightly, and not for a feature that isn't significantly valuable to warrant it.

HaloFour commented 7 years ago

@corliss

The difference being that instead of there being a list of reasonable identifiers/keywords that the Intellisense must now assume that literally anything already typed could also be a newly declared identifier. In order to not break existing muscle memory Intellisense must always assume that even if the current token might be a new identifier that it's not going to be. That would make the experience pretty awful for the people who might want to adopt the new syntax.

CyrusNajmabadi commented 7 years ago

If the user wants := they select that from the list or hit Escape.

You're now making it so that people have to take extra steps to get the syntax you want. That's an extra burden on them and will make the typing experience less pleasant.

I mean... how good will you feel about having to type, for every new variable, tok<down><down><down><down><space> or tok<esc>? :)

We design our language with teh consideration of IDE scenarios in mind, and with the known expectations people have about the tooling we provide. That was a core reason, for example, that our linq-query syntax developed like it did. We have from <id> in <expr> for a very specific reason. So that the variables will be known before they are used later in the query. That's why we did not go with traditional SQL syntax (where the from-clause is at the end) because it would interfere greatly in an environment where the tooling is actively assisting the user.

CyrusNajmabadi commented 7 years ago

Also please don't change a single to 4 's.

Why not? There may be 4 items that match 'tok' that would be listed above tok :=.

Intentional exaggeration is not something I want to defend against.

It's not intentional exaggeration. It's trying to realistically assess what the experience could be like for users.

I'm not bringing up this argument haphazardly. I'm pointing out explicitly the complication that your feature is adding to the language. You are introducing syntax which introduces a left-ambiguity between a word being a keyword, symbol reference, or symbol declaration. That is a something we have experience with and something which can be quite problematic to the IntelliSense experience.

Again, you have to think in terms of muscle memory. Muscle memory means that people have expectations that what they type will produce the same results. Tweaking that is something you need to be extremely careful around.

We also need to consider the mainline case for both styles of users. Let's say we have a user who really likes :=. They now potentially have to take this extra step on every declaration they type. And that extra step may rquire keys that are quite annoying for typing**.

**This is not hypothetical BTW. On my keyboard, typing arrows or escape are both extremely unpleasant. They take me out of my core keyboard space and really interfere with smooth typing.

--

My overall point is that these issues must be considered. Your proposal puts forth := almost entirely from a readability perspective. As someone working on the tooling, i have to strongly consider the perspective of how conducive this is for actual writing of code in the context of the tools we already have.

CyrusNajmabadi commented 7 years ago

As a data point: We introduced a bug that affected how enums were preselected automatically when typing. The impact on the team was incredibly annoying. And, unfortunately, before we fixed it, it escaped into the wild. We got tons of feedback from people who were incredibly thrown off by what was happening.

These people could work around the issue by using the arrow keys, or 'esc', but such typign patterns would be substantially aggravating to them.

CyrusNajmabadi commented 7 years ago

(after all the user doesn't memorize list entries from one version of Visual Studio to the next!)

Of course they do. Even i do this :)

That's what muscle-memory is. You get used to interacting with the tooling in a certain way, to the point that you're just doing it automatically.

CyrusNajmabadi commented 7 years ago

@corliss I'm not jumping the gun. I do understand what you're saying. And i'm telling you from 15+ years of direct experience on this topic **, that what you said is incorrect. People, including myself, do memorize list entries, and they do build up an automatic muscle memory expectation of where things are.

We have screwed this up in this past, and we do hear about it almost immediately.

--

** Some background: I've worked on and have owned IntelliSense and the editing experience here since i started working at MS. I've worked on several rewrites of these systems, and i can tell you that even incredibly subtle changes are felt by our users. Sometimes we must make the change (like with lambdas), or we feel like there is substantial benefit to a change, even if it means negatively affecting so many people when we do it. But, like with a language change, there is an enormously high bar to cross to warrant it.

Look, if you don't want to do this proposal

I am simply providing you with my full opinion on hte subject. As someone who files suggestions and issues myself, i do not want someone haphazardly closing things with little justification or explanation of the decision. I'd rather try to explain the concern fully versus leaving questions out there.

Now, it's clear, you don't necessarily agree with me on my assessment about the potential costs of this approach. i.e. " I'm personally satisfied that there isn't much of an impact on intellisense, and have no more to say." That's totally fine. But to me, having investigated this space from tons of different directions, i'm definitely not in that state. I have deep concerns and reservations about this. And that's ok :)

but jumping around reactively is painful.

I think you are bringing you own preconceived notions here. This is my job, and i would be remiss if i did not put my full attention and care into assessing the potential downsides of these suggestions. I'm trying to condense out everything we've learned over decades of doing this into a few paragraphs to help provide insight on the scenario. Invariably that sort of communication is going to be problematic. There is so much information to convey, and it's not going to be suitable to spend days crafting an entire response that covers every aspect in depth. For now, i may condense down years of learning, into a few sentences. If you want to know more about it, i'm happy to expand. But you're going to get what i think is an acceptable response as it best pertains to what has been stated so far :)