Fix variable "splatting"

/cc @pearkes - This is something you'd care about. 

This PR fixes a lot of issues surrounding "splatting", such as `${instance.name.*.id}`. 

For historical reasons, and because not many people understood it before this PR, I'll explain the prior state (before this PR). The above variable would be literally "splatted" into a comma-separated value list. So, for example `${foo.bar.*.id}` might become `abc,def,ghi` (3 IDs), literally. So if you had a configuration that took a list such as `instances = ["${foo.bar.*.id}"]`, then it would be up to the provider to split this up. This kind of worked, but its certainly confusing. And there are a _lot_ of edge cases where it just didn't work at all.

This PR fixes the known issues surrounding splatting by doing the following:

* The variable now turns into a specially formatted string that signals to Terraform that it is an array.
* Array values now turned into an error _prior_ to ever being sent to the provider. Providers no longer need to account for splatting in any way. 
* Diffs properly show computed values. So if you splat a list with a computed value, the diff will properly show: `list.#: 0 => "<computed>"` (since the number of list elements can't be known until the splat is not computed).
* Splats can _only_ be used directly within arrays. So you can do this: `instances = ["${foo.bar.*.id}"]`, but you can't do this: `port = "${foo.bar.*.id}"`. 
* To make splats more useful outside of lists, the `join` function was introduced. This will join the array elements by a single user-provider delimiter. Example: `${join(",", foo.bar.*.id)}`. And this can be used anywhere.
* Fixed a lot of core issues around this whole thing.

The end result is no backwards incompatibility, except perhaps if you were using splats outside of lists before. But this can easily be fixed with `join`. And the feature should actually work quite well now.