Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 18 | Comments: 72

filter by tags archive

ChallengeC# Rewriting

time to read 1 min | 87 words

Here is an interesting one. Can you write code that would take the first piece of text and would turn it into the second piece of text?

First (not compiling)

image

Second (compiling):

image

Hint, you can use NRefactory to do the C# parsing.

More posts in "Challenge" series:

  1. (28 Apr 2015) What is the meaning of this change?
  2. (26 Sep 2013) Spot the bug
  3. (27 May 2013) The problem of locking down tasks…
  4. (17 Oct 2011) Minimum number of round trips
  5. (23 Aug 2011) Recent Comments with Future Posts
  6. (02 Aug 2011) Modifying execution approaches
  7. (29 Apr 2011) Stop the leaks
  8. (23 Dec 2010) This code should never hit production
  9. (17 Dec 2010) Your own ThreadLocal
  10. (03 Dec 2010) Querying relative information with RavenDB
  11. (29 Jun 2010) Find the bug
  12. (23 Jun 2010) Dynamically dynamic
  13. (28 Apr 2010) What killed the application?
  14. (19 Mar 2010) What does this code do?
  15. (04 Mar 2010) Robust enumeration over external code
  16. (16 Feb 2010) Premature optimization, and all of that…
  17. (12 Feb 2010) Efficient querying
  18. (10 Feb 2010) Find the resource leak
  19. (21 Oct 2009) Can you spot the bug?
  20. (18 Oct 2009) Why is this wrong?
  21. (17 Oct 2009) Write the check in comment
  22. (15 Sep 2009) NH Prof Exporting Reports
  23. (02 Sep 2009) The lazy loaded inheritance many to one association OR/M conundrum
  24. (01 Sep 2009) Why isn’t select broken?
  25. (06 Aug 2009) Find the bug fixes
  26. (26 May 2009) Find the bug
  27. (14 May 2009) multi threaded test failure
  28. (11 May 2009) The regex that doesn’t match
  29. (24 Mar 2009) probability based selection
  30. (13 Mar 2009) C# Rewriting
  31. (18 Feb 2009) write a self extracting program
  32. (04 Sep 2008) Don't stop with the first DSL abstraction
  33. (02 Aug 2008) What is the problem?
  34. (28 Jul 2008) What does this code do?
  35. (26 Jul 2008) Find the bug fix
  36. (05 Jul 2008) Find the deadlock
  37. (03 Jul 2008) Find the bug
  38. (02 Jul 2008) What is wrong with this code
  39. (05 Jun 2008) why did the tests fail?
  40. (27 May 2008) Striving for better syntax
  41. (13 Apr 2008) calling generics without the generic type
  42. (12 Apr 2008) The directory tree
  43. (24 Mar 2008) Find the version
  44. (21 Jan 2008) Strongly typing weakly typed code
  45. (28 Jun 2007) Windsor Null Object Dependency Facility

Comments

Roy Osherove

sounds like something I'd use method_missing for...

but I'd need VB or C# for dynamic types first

Nathaniel Neitzke

I also have been working on a document style database, mostly learning Erlang to understand CouchDB. I am curious about your choice of C# for the views though, it seems like you would want to use the DLR or boo for something like that. I can see where C# support would be nice but when you get to the point where you are doing this type of stuff in C# it is fitting a square peg in a round hole imho.

Andrew Davey

How about you define the interface of the document type you are retreiving first. Then write the query with that.

It's like saying "I am going to get things that look like this ..."

followed by "this is how I do that".

Justin Chase

You could in C#4.0 if docs was a dynamic object. No need for NRefactory just implement method missing and pass in the xml document object.

josh

I agree with Nathaniel. Seems like a little quackfu goodness with Boo would make the syntax nicer. /just me

Frank Quednau

Interestingly it's an expression. You could write against any ol' interface, parse the expression and create a new one that looks like the second.

Alternatively a regular expression should work well :)

Jan Limpens

I actually prefer the second, compiling expression. It is more obvious what is happening and as doc.Title will not give me intellisense anyway, whats the motive of this syntax sugar?

When I first read this in the other post, I assumed that doc.Title was a regular property every doc has.

Ayende Rahien

Roy,

Not really. If you pound C# hard enough, you can generate dynamics.

Ayende Rahien

Nathaniel,

Take a look at the view syntax, vs. the couch db syntax.

I find that linq make this a LOT simpler. It is also resolving a lot of problems relating to how to create indexed views without schema.

Ayende Rahien

Andrew,

That is too much work.

The data is already there, having to specify it twice is violation of DRY

Ayende Rahien

Justin,

Yes, I know.

I am not willing to be tied to C# 4.0

Ayende Rahien

Josh,

Yes, it would.

But Boo doesn't have full Linq support yet, and in this case, Linq really IS the best syntax for this.

Ayende Rahien

Frank,

I am not sure how you would get this to compile against "any old interface", when you don't know what the interface is in the first place.

Ayende Rahien

Jan,

The second syntax is uglier, and it exposes implementation details that I would rather not have.

The idea is to get a nicer syntax for things.

configurator

Ayende, I suggest rewriting the linq expressions, and not the C# code.

The pro is that no precompilation rewriting is necessary.

The con is that some interface has to be defined - but only so that the code will compile.

Tuna Toksoz

Looks similar to what we used to do with NH Linq :)

yug
yug

I agree with configurator, wouldn't touching the LINQ expressions be easier than introduction another layer of complexity?

Stefan Wenig

Confusing your whole tool chain - from R# to the debugger and back - with a small precompilation trick sounds bad enough. The verbose version is not that bad after all.

But dismissing the whole notion of defining interfaces (or schemas for that matter, where's the difference) as a violation of DRY?

Anyway, just defining the interfaces would not get you working code.. You might want to consider the XML features of VB (import <schema.xsd) - it's an excellent DSL for processing XML, and it might be extensible to map those XML properties to an indexer if you implement some funny interface.

Ayende Rahien

configurator,

I don't want to do that, I see this as a violation of DRY.

Ayende Rahien

Stefan,

I think that you are missing something, because I haven't explained it.

There isn't anything else here. Literally.

The code on this post is all the code that is required to create a view.

You are not going to be able to use standard tools anyway.

Stefan Wenig

As some people already pointed out, your first example will compile if you statically define an interface for doc. The advantage would be that you don't have to modify the tool chain (i.e., precompile C#).

I'm just saying that this will compile, but you still need to implement that interface (either statically or dynamically) in order for this code to work at run time.

(As for the rest of our answer: is this some kind of trick question where the real challenge is figuring out what the rules of the game are? I thought you're asking for that precompiler?)

configurator

I don't see how defining a property is a violation of DRY. Is that property defined anywhere else? In the document itself, of course, but wouldn't the producer of the document (i.e. the same program) need the exact same interface anyway?

What good is a document that you can't access? And you can't access the document if you don't have an interface to access it with.

configurator

If I understand you correctly, what you want is for all documents to always be dynamically bound (i.e. C# 4 type dynamic), never accessing them anyway else.

I can't shake the feeling that you are trying to coerce the language into something that it is not - a late-bound language. If you want a late-bound language, use VB or C# 4.

Ayende Rahien

Stefan,

No, this is not a trick question.

The problem is that when trying to change the parameters of the question, you are not aware of the context in which it is going to operate, so you are making the wrong assumptions.

There is going to be a pre compiler step anyway, so the objection about not having to change the tool chain is not valid. At that point, you might as well squeeze the most out of this operation, because good syntax matter.

Ayende Rahien

configurator,

You are confusing the db side code and the client side code. They are not in sync, not kept together and in general should be separated.

As such, when defining a view, having to define an interface for the view is redundant and violate DRY.

And yes, I am doing things that the language was never meant to do. That is part of the fun, because the end result is going to be worth it.

Stefan Wenig

I guess I'll have to wait for the answer to that challenge before I have a chance to understand your answers to my comments.

I was not trying to answer your question. Although it sounds interesting, I don't know the first thing about NRefactory and I'm lazy, so I'll just wait for the answer and then go look into NRefactory.

Neither was I changing the parameters of the question. I got off on a tangent about an alternative solution using interfaces with some other readers. And I made a general comment about whether the solution, as you defined it, would be worth a modification to the tool chain. I have thought about transformations in some cases where C# is unneccessarily limited (attribute argument types, for instance), and a simple precompiler step could bring huge benefits. Still, modifying the tool chain is a problem itself, and I finally decided not to do it.

But that''s not a relevant discussion if this is considered a challenge just for fun, so feel free to ignore my comments ;-)

Stefan Wenig

BTW, I just checked whether VB's XML support could help out here.

The syntax doc.Type == page would become doc.@Type = page in VB. That looks good enough (although only for string values, I didn't look any further).

However, VB's XML literals are unneccesarily bound to the XElement type (and some related types).

The resolution of .@Type is done via an extension method (AttributeValue) that VB will define for any assembly that uses those XML literals, but it will not use a user-provided method for other types. Also, the relevant methods in XElement are not virtual. (There might be a hack when you reach really deep into the data structures of XElement, but that's a place where I don't want to be.)

Unbelievable.

Ayende Rahien

Stefan,

I actually got to talk with the guy who implemented that feature not long ago.

That was an intentional decision on Microsoft part. They did not want to deal with supporting this extensibility story.

Stefan Wenig

Of course it is, that's just how they are wired. "Hey, this looks useful - can we make it internal?"

But making a framework's guts internal is one thing. While I don't agree with this default, at least they have given some good reasons. But binding a language's data access syntax to a non-virtual method of a concrete class is just ... unbelievable. I can't even access XML data without loading it into an XElement first.

There goes the idea of VB being my favorite DSL for XML ... at least the more interesting part of it.

Andrey Shchekin

I would never want to do this. Did you like object-typed parameter in ASP.NET MVC? Dynamics (compile-time or runtime) are are problem waiting to happen.

Just use a generator to get a typed interface from the existing schema (you can easily do it through the pre-compile step), then compile this code referencing the generated interface.

If the DB has to be completely separated from this code, just extract some kind of schema from the DB (automatically), then generate an interface based on this schema.

Ayende Rahien

Andrey, there is no schema.

It is the view that defines the schema, and trying to define it twice is a waste of time.

Andrey Shchekin

Ok, I read the CouchDB docs and it seems I understand the situation now.

Another question -- so you need a preprocessor since you do not only need to infer a schema, you also actually want to compile this (optionally using PLINQ or whatever)?

Otherwise you could just go with NRefactory without a compile step at all?

Ayende Rahien

Yes, I do want to compile this

Stefan Wenig

I read that wrong, I thought you were talking about extending C# with additional tooling, but this is about compiling code snippets from text fields, right?

Now everything makes sense, sorry for being so balky.

I still have reservations about not having a schema for the actual data though. The view makes up the schema, alright. But the view is created upon existing data, which should comply to one or more schemas (whether explicit or implicit), unless the view code is completely heuristic. That's a general problem that I have with schema-less data though. You avoid n schema migrations, but you have to deal with n versions of your data in the latest version of your code. But maybe that's just me being too enterprisey ;-)

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. RavenDB 3.0 New Stable Release - 7 hours from now
  2. Production postmortem: The industry at large - about one day from now
  3. The insidious cost of allocations - 2 days from now
  4. Buffer allocation strategies: A possible solution - 5 days from now
  5. Buffer allocation strategies: Explaining the solution - 6 days from now

And 3 more posts are pending...

There are posts all the way to Sep 11, 2015

RECENT SERIES

  1. Find the bug (5):
    20 Apr 2011 - Why do I get a Null Reference Exception?
  2. Production postmortem (10):
    01 Sep 2015 - The case of the lying configuration file
  3. What is new in RavenDB 3.5 (7):
    12 Aug 2015 - Monitoring support
  4. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
View all series

RECENT COMMENTS

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats