Statically typed? Compiler checked? Ha!
Just a nod toward the people that cling to static typing with both hands, their teeth and the tail:
RouteTable.Routes.Add(new Route { Url = “admin/[controller]/[action]“, Defaults = new { Controller = “Admin“, Acton = “Index” }, Validation = new { Conrtoller = “Admin|Users|Categories” }, RouteHandler = typeof(MvcRouteHandler) });
Now, instead of abusing the language to get this, can we get first class support for this things?
Comments
Unfortunately actually getting those properties like Controller, Action out of the anonymous type you need to use a TypeDescriptor and some reflection. Not great.
It would be cool if you could use Interfaces like:
new IRouteDefaults {
Controller = "Admin",
Action = "Index",
NotPartOfInterface = "ExtraProp"
}
Conrtoller? ouch, unless that was just a blog-typo. :-p
'new IRouteDefaults {' is ok, but my ideal compiler would just infer from the assignment that the anonymous type it generates should implement IRouteDefaults automatically.
Is not it a first-class support?
The only problem is that it is not easy to get data out of it, but I think that was something C# architects wanted more time to think about.
You mean the ability to define a hash table like:
IDictionary<string, object> values = {"Foo"=123, "Bar"="bar"};
I'd love that too. ;)
Luke,
That was intentional, and that isn't the only one.
Nick,
How would it know to use the IRouteDefaults?
Andrey,
No, this is an abuse of a language feature that was never meant to be use this way.
Andrey,
No, this is an abuse of a language feature that was never meant to be use this way.
Phil,
Hm, that isn't good enough, you really want symbols for something like that.
Symbols? Not sure I understand why.
For example, what if I want this:
IDictionary<string, object> values = {"Footie Tutie"=123, "#)$*(&)#"="bar"};
or
IDictionary<MyObj, object> values = {new MyObj(1), new MyObj(2)="bar"};
What would that look like using symbols?
They wouldn't. Although I challenge you to come up with a good reason to use "#)$*(&)#" as a dictionary key.
The reason that I am saying that you want symbol is that you are trying to get sybmols now. It has to do with the amount of
Hmm...
Symbols are necessary in Ruby because strings are mutable, but symbols are not. Thus:
hash1 = {"red" => "foo"}
hash2 = {"red" => "foo"}
(totally valid in Ruby) would have two different memory locations for the key "red".
But with symbols:
hash1 = {:red => "foo"}
hash2 = {:red => "foo"}
:red in both hashes refer to the same memory location.
It seems to me that since strings are immutable with .NET, string interning provides the same benefit as symbols do in Ruby.
So the only benefit of a symbol would be that you don't have to use quotes? You do have to use quotes for a symbol in ruby if you have spaces in the symbol.
:"my symbol"
The .NET equivalent is even shorter:
"my symbol"
I don't think this is semantic cruft at all to require quotes when it effectively is equivalent to the purpose of a symbol. A symbol is a simply a const literal within Ruby.
Phil,
I disagree. I think that syntactic sugar is super important, because it make the difference between an acceptable solution and something that you turn your nose at.
Syntactic sugar for what?
In Ruby, this makes sense because in Ruby...
:foo != "foo"
Since strings are mutable and not interned in Ruby, it makes sense to have syntactic sugar for an immutable literal string. Because you don't already have syntax for that.
But in C#
:foo in Ruby == "foo" in C#
They mean the exact same thing.
So I don't understand why you'de have :foo = "foo" in C# as "syntactic sugar".
Let me pose it to you in another way. Should Ruby have the following syntactic sugar?
foo
Where # is syntactic sugar for a mutable string? In other words:
foo = "foo"
I mean, isn't that extra quote semantic cruft? ;)
If Ruby strings were immutable and interned like they are in .NET, I'm guessing there'd be no need for symbols in Ruby.
Phil
Phil,
You are focusing on an implementation detail that is rather unimportant from my point of view.
I am not talking about the immutability or mutability of strings, or whatever you can compare a symbol to a string or vice versa.
I am talking that it is much easier to read :this than "this". You have been trained that "this" is not text that should mean anything, it is just "text".
What I am saying is that this distinction is important. It is going to be helpful for both humans and tools that needs to deal with this.
Can you tell me how you are going to do a "symbol" rename, for example?
From the point of view of the reader, giving it a special status gives it special attention.
After some thinking, I agree with you. But I do not agree that symbols are compelling enough to hack the language to support them. In VB you can do dict!Value, which basically means dict["Value"], but I used it rarely because it was too easy to mistake this with something checked by the compiler.
What I would somewhat like too see would be actual checks:
string controller = "controller";
string action = "action";
RouteTable.Routes.Add(new Route {
Url = $“admin/[${controller}]/[${action}]“,
Defaults = new {
{ controller, “Admin“ },
{ acton, “Index” }
},
Validation = new {
{ controller, “Admin|Users|Categories” }
},
RouteHandler = typeof(MvcRouteHandler)
});
with string interpolation, type inference (infers Dictionary) and real compile-type checking. The one things that seems redundant is
string controller = "controller";
but I can not think of language feature than fix this without losing the advantages of checking. Basically, we are saying here that this symbol is known and will be used, as opposed to "cntroller", "controler" or "control", which will be allowed by Ruby checker.
So in the case of the hash, the "special status" is that it's a key to a hash. I see.
Your symbol rename agument defeats me. I concede. :)
Though... I must point out the dangers in assuming that symbols make renaming safe. If I use :foo in one context and :foo in another, I'd be in danger if I did a symbol rename and those contexts were different.
So with symbols, you've solved the find and replace issue with renaming a symbol vs a string (aka with "red" and :red are differentiated).
But you haven't solved:
hash = {:red => "foo"}
some_method :red = "bar"
Where :red in both cases means different things.
Of course, it's probably just a "running with scissors" moment in which you need to be sure that symbols are unique globally when they are a symbol for the same thing, since renaming a symbol limited by scope would be problematic too:
def foo(hash)
puts hash[:red]
end
def bar()
hash = {:red => "foobar"}
end
A rename limited to scope wouldn't know that :red in both methods are the same thing and should both be renamed.
In any case, an interesting idea.
Doesn't string constants "solve" the missing symbol feature "issue", or am I missing something else?
Why not just use a language that supports that kind of construct? C# is not a be and do everything for everyone. If you want a more expressive language than C#, then use a language that is more expressive than C#...Go play with the DLR or ruby...and yes i love static typed languages :)
@Gauthier - yes a string constant would solve this "issue." I am surprised that your are the only one to notice the strawman...
Comment preview