Ayende @ Rahien

Refunds available at head office

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

Adam Tybor
12/20/2007 09:21 PM by
Adam Tybor

Unfortunately actually getting those properties like Controller, Action out of the anonymous type you need to use a TypeDescriptor and some reflection. Not great.

Adam Tybor
12/20/2007 09:24 PM by
Adam Tybor

It would be cool if you could use Interfaces like:

new IRouteDefaults {

Controller = "Admin",

Action = "Index",

NotPartOfInterface = "ExtraProp"

}

Luke Breuer
12/20/2007 09:27 PM by
Luke Breuer

Conrtoller? ouch, unless that was just a blog-typo. :-p

Nick
12/20/2007 09:35 PM by
Nick

'new IRouteDefaults {' is ok, but my ideal compiler would just infer from the assignment that the anonymous type it generates should implement IRouteDefaults automatically.

Andrey Shchekin
12/20/2007 09:38 PM by
Andrey Shchekin

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.

Haacked
12/20/2007 09:55 PM by
Haacked

You mean the ability to define a hash table like:

IDictionary<string, object> values = {"Foo"=123, "Bar"="bar"};

I'd love that too. ;)

Ayende Rahien
12/20/2007 10:18 PM by
Ayende Rahien

Luke,

That was intentional, and that isn't the only one.

Ayende Rahien
12/20/2007 10:19 PM by
Ayende Rahien

Nick,

How would it know to use the IRouteDefaults?

Ayende Rahien
12/20/2007 10:20 PM by
Ayende Rahien

Andrey,

No, this is an abuse of a language feature that was never meant to be use this way.

Ayende Rahien
12/20/2007 10:20 PM by
Ayende Rahien

Andrey,

No, this is an abuse of a language feature that was never meant to be use this way.

Ayende Rahien
12/20/2007 10:22 PM by
Ayende Rahien

Phil,

Hm, that isn't good enough, you really want symbols for something like that.

Haacked
12/20/2007 10:26 PM by
Haacked

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?

Ayende Rahien
12/20/2007 10:31 PM by
Ayende Rahien

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

Haacked
12/20/2007 11:18 PM by
Haacked

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.

Ayende Rahien
12/20/2007 11:23 PM by
Ayende Rahien

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.

Haacked
12/20/2007 11:29 PM by
Haacked

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

Ayende Rahien
12/20/2007 11:34 PM by
Ayende Rahien

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.

Andrey Shchekin
12/20/2007 11:48 PM by
Andrey Shchekin

No, this is an abuse of a language feature that was never meant to be use this way.

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.

Haacked
12/20/2007 11:52 PM by
Haacked

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.

Gauthier Segay
12/22/2007 12:19 AM by
Gauthier Segay

Doesn't string constants "solve" the missing symbol feature "issue", or am I missing something else?

jmorris
12/22/2007 02:56 AM by
jmorris

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 :)

jmorris
12/22/2007 03:59 AM by
jmorris

@Gauthier - yes a string constant would solve this "issue." I am surprised that your are the only one to notice the strawman...

Comments have been closed on this topic.