Ayende @ Rahien

Unnatural acts on source code

Dense code

Yes, it is dense, but I also find it beautiful:

image

Comments

Michael Morton
05/09/2009 08:47 AM by
Michael Morton

I agree, very elegant. Never quite occurred to me to do caching in this way, but it does make sense. Definitely something I will have to consider in the future.

JeroenH
05/09/2009 09:41 AM by
JeroenH

Personally, I don't really like linq syntactic sugar.

To me, this is just as clear, if not clearer:

queriesLookup.Values

.Select(agg => new QueryAggregationSnapshot

  {

      ...

  }

.Cast <iqueryaggregationsnapshot
.ToArray()

Sasha Goldshtein
05/09/2009 09:44 AM by
Sasha Goldshtein

What I don't like is that it's a little difficult to debug. For example, if I wanted to know the value returned by Read() or by Write(), I would have to work quite hard.

When writing a public method such as this one, I often would assign the return values to variables and test the variables explicitly to facilitate debugging.

Chris Martin
05/09/2009 10:08 AM by
Chris Martin

Lame...even gay; if you ask me. ;)

Thomas Eyde
05/09/2009 10:43 AM by
Thomas Eyde

Too dense for my taste. Too many things happens at once, so I have a hard time figuring out what is going on.

Dave
05/09/2009 11:04 AM by
Dave

@Sasha. Outside the function itself it shouldn't matter if the result cam from cache or was freshly created.

I don't know how you write your tests, but I hope you don't started testing cached in the GetReportSnapshot tests. As GetReportSnapshot depends on cached, it's safe to assume cached would work properly as that part is covered elsewhere.

Why would you give the GC a lot of work only so you can when you have a problem set a breakpoint? If you ever would encounter a problem in the GetReportSnapshot method, just add the intermediate (result) variable just for debugging. When you're done debugging, don't forget to remove the variable. With all the tears and layers I have enough overhead performance penalties. I don't need extra penalties.

noone
05/09/2009 01:14 PM by
noone

Frankly, I see nothing bug ugly.

Colin Jack
05/09/2009 03:01 PM by
Colin Jack

Too dense for me.

Frank Quednau
05/09/2009 03:46 PM by
Frank Quednau

What's with the unused "snapshots" variable? You could write

_ => ...

Should look even more dense ;)

And why is the type of "agg" so similar to the QueryAgg..Snapshot type?

Anyway, I like it.

Omer Mor
05/09/2009 04:20 PM by
Omer Mor

Do you really need to turn the result into an array ( .ToArray() ) at the end?

Jeremy Gray
05/09/2009 04:40 PM by
Jeremy Gray

@Omer - Yes, in order to force evaluation and convert the results into a form that can be safely cached and reused.

Ayende Rahien
05/09/2009 05:25 PM by
Ayende Rahien

Frank,

The unused value is the previous value for the item, which allow you to make modifications. It is not used here.

The reason for this is that I want to create an immutable snapshot

Ayende Rahien
05/09/2009 05:26 PM by
Ayende Rahien

Omer,

If I wouldn't do that, I would cache the query itself, not the query results

nightshade427
05/09/2009 06:07 PM by
nightshade427

Very nice code! I noticed that ever since I started using ruby, my code is starting to look more and more succinct like this in C#. Couldn't the projection be made simpler without the assignments?

Jacob
05/09/2009 08:33 PM by
Jacob

I like it. To me it's not about density or beauty, it's about readability. Your example has that (largely due to your formatting and whitespace). Nice.

PandaWood
05/10/2009 07:04 AM by
PandaWood

I think it's just right

Martin
05/11/2009 08:31 AM by
Martin

Couldn't caching be achieved without the GetReportSnapshot method itself care about the cashing?

Ian Chamberlain
05/11/2009 09:38 AM by
Ian Chamberlain

Pity the poor person who has maintain it years from now.

Dense code is bad for testing, bad for understanding and bad for maintenance.

For me this is the opposite of elegance.

Kelly Stuard
05/11/2009 02:33 PM by
Kelly Stuard

You're probably going through a fair amount of work to make cached.Read() work without any passed in information. I would see you more as the type of person who would use aspect oriented programming to do:

[Cached]

public IEnumerable <iqueryaggregationshapshot GetReportSnampshot()

and have it do the

cached.Read followed by the wonderfully compact write.

Jeff Brown
05/11/2009 08:23 PM by
Jeff Brown

This looks like memoization. Here's my variation on this:

private Memoizer <ireportsnapshot reportSnapshotMemoizer = new Memoizer <ireportsnapshot();

public IReportSnapshot GetReportSnapshot()

{

reportSnapshotMemoizer.Memoize(() =>

{

    // obtain snapshot

    return reportSnapshot;

});

}

Another variation I use in Gallio is a KeyedMemoizer <tkey,> which is basically a simple dictionary-based lazily populated cache.

Jeff Brown
05/11/2009 08:24 PM by
Jeff Brown

Doh! I missed a "return" statement in there.

return reportSnapshotMemoizer.Memoize(() => ....);

Comments have been closed on this topic.