ChallengeC# Rewriting
time to read 1 min | 87 words
More posts in "Challenge" series:
- (03 Feb 2025) Giving file system developer ulcer
- (20 Jan 2025) What does this code do?
- (01 Jul 2024) Efficient snapshotable state
- (13 Oct 2023) Fastest node selection metastable error state–answer
- (12 Oct 2023) Fastest node selection metastable error state
- (19 Sep 2023) Spot the bug
- (04 Jan 2023) what does this code print?
- (14 Dec 2022) What does this code print?
- (01 Jul 2022) Find the stack smash bug… – answer
- (30 Jun 2022) Find the stack smash bug…
- (03 Jun 2022) Spot the data corruption
- (06 May 2022) Spot the optimization–solution
- (05 May 2022) Spot the optimization
- (06 Apr 2022) Why is this code broken?
- (16 Dec 2021) Find the slow down–answer
- (15 Dec 2021) Find the slow down
- (03 Nov 2021) The code review bug that gives me nightmares–The fix
- (02 Nov 2021) The code review bug that gives me nightmares–the issue
- (01 Nov 2021) The code review bug that gives me nightmares
- (16 Jun 2021) Detecting livelihood in a distributed cluster
- (21 Apr 2020) Generate matching shard id–answer
- (20 Apr 2020) Generate matching shard id
- (02 Jan 2020) Spot the bug in the stream
- (28 Sep 2018) The loop that leaks–Answer
- (27 Sep 2018) The loop that leaks
- (03 Apr 2018) The invisible concurrency bug–Answer
- (02 Apr 2018) The invisible concurrency bug
- (31 Jan 2018) Find the bug in the fix–answer
- (30 Jan 2018) Find the bug in the fix
- (19 Jan 2017) What does this code do?
- (26 Jul 2016) The race condition in the TCP stack, answer
- (25 Jul 2016) The race condition in the TCP stack
- (28 Apr 2015) What is the meaning of this change?
- (26 Sep 2013) Spot the bug
- (27 May 2013) The problem of locking down tasks…
- (17 Oct 2011) Minimum number of round trips
- (23 Aug 2011) Recent Comments with Future Posts
- (02 Aug 2011) Modifying execution approaches
- (29 Apr 2011) Stop the leaks
- (23 Dec 2010) This code should never hit production
- (17 Dec 2010) Your own ThreadLocal
- (03 Dec 2010) Querying relative information with RavenDB
- (29 Jun 2010) Find the bug
- (23 Jun 2010) Dynamically dynamic
- (28 Apr 2010) What killed the application?
- (19 Mar 2010) What does this code do?
- (04 Mar 2010) Robust enumeration over external code
- (16 Feb 2010) Premature optimization, and all of that…
- (12 Feb 2010) Efficient querying
- (10 Feb 2010) Find the resource leak
- (21 Oct 2009) Can you spot the bug?
- (18 Oct 2009) Why is this wrong?
- (17 Oct 2009) Write the check in comment
- (15 Sep 2009) NH Prof Exporting Reports
- (02 Sep 2009) The lazy loaded inheritance many to one association OR/M conundrum
- (01 Sep 2009) Why isn’t select broken?
- (06 Aug 2009) Find the bug fixes
- (26 May 2009) Find the bug
- (14 May 2009) multi threaded test failure
- (11 May 2009) The regex that doesn’t match
- (24 Mar 2009) probability based selection
- (13 Mar 2009) C# Rewriting
- (18 Feb 2009) write a self extracting program
- (04 Sep 2008) Don't stop with the first DSL abstraction
- (02 Aug 2008) What is the problem?
- (28 Jul 2008) What does this code do?
- (26 Jul 2008) Find the bug fix
- (05 Jul 2008) Find the deadlock
- (03 Jul 2008) Find the bug
- (02 Jul 2008) What is wrong with this code
- (05 Jun 2008) why did the tests fail?
- (27 May 2008) Striving for better syntax
- (13 Apr 2008) calling generics without the generic type
- (12 Apr 2008) The directory tree
- (24 Mar 2008) Find the version
- (21 Jan 2008) Strongly typing weakly typed code
- (28 Jun 2007) Windsor Null Object Dependency Facility
Comments
sounds like something I'd use method_missing for...
but I'd need VB or C# for dynamic types first
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.
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".
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.
I agree with Nathaniel. Seems like a little quackfu goodness with Boo would make the syntax nicer. /just me
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 :)
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.
Here: http://snipt.org/KP
Transforms the example above but there is no guarantee that it will work for anything slightly different :)
Roy,
Not really. If you pound C# hard enough, you can generate dynamics.
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.
Andrew,
That is too much work.
The data is already there, having to specify it twice is violation of DRY
Justin,
Yes, I know.
I am not willing to be tied to C# 4.0
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.
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.
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.
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.
Looks similar to what we used to do with NH Linq :)
I agree with configurator, wouldn't touching the LINQ expressions be easier than introduction another layer of complexity?
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.
configurator,
I don't want to do that, I see this as a violation of DRY.
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.
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?)
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.
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.
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_.
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.
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 ;-)
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.
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.
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.
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.
Andrey, there is no schema.
It is the view that defines the schema, and trying to define it twice is a waste of time.
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?
Yes, I do want to compile this
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