Tuesday, June 17, 2014

How to avoid the expensive ToList on generic list? Generics' OOPness redux

Have you questioned C# generics’ OOPness? Why is C# is not allowing us to return List<Autobot> to List<ITransformer> despite Autobot and Decepticon is an ITransformer?

This won't compile even Autobot implements ITransformer:



Can fix it with ToList, but it's an expensive operation, as it creates a copy:
public static List<ITransformer> GetTransformers(TransformerType t)
{
    if (t == TransformerType.Autobot)
        return GetAutobots().ToList<ITransformer>();
    else if (t == TransformerType.Decepticon)
        return GetDecepticons().ToList<ITransformer>();
         
    return null;
}   


To cut to the chase, return the List<ConcreteClass> to IEnumerable<Interface>:
public static IEnumerable<ITransformer> GetTransformersOop(TransformerType t)
{
    if (t == TransformerType.Autobot)
        return GetAutobots();
    else if (t == TransformerType.Decepticon)
        return GetDecepticons();
         
    return null;
}

Live code: https://dotnetfiddle.net/K3IcR5

For further information why List<ConcreteClass> is not compatible to List<Interface> even the concrete class implements the interface, read about covariance

Saturday, June 14, 2014

ORM Choice

ORM choice is a touchy subject, you can't just choose one without riling up some developers or DBAs in your team, it's a choice that must be decided carefully. When you've chosen the right ORM for the project, it is a shared joy for the team; picking the wrong one gives everyone a shared pain


As ORM has an influence how we model the domain models (facilitates shared vocabulary between the developers and the users), we should have a strategy when choosing one (or even two) for your project. We should also have a strategy when modeling our domain models. When we choose an ORM, we must embrace its principles, advantages, limitations, warts and all


And also, there are some who hates ORM, I could articulate some of the reasons why some hates ORM, but it's better to leave that to the experts. Here's the takeaway why some hates ORM, and Martin Fowler can't be wrong on positing that:

much of the frustration with ORMs is about inflated expectations


Back to the subject on choosing an ORM


You might think that this ORM drivel is about my repository framework (a repository framework to prevent the high coupling of an application to an specific ORM) I'm trying to endorse. I would not endorse it, it's a half-baked solution for what it's trying to achieve


I made a repository framework that encapsulates both Entity Framework and NHibernate in my earnest attempt to keep a project from being too coupled to an specific ORM framework. I named it ToTheEfNhX, short for: To The Entity Framework and NHibernate Elimination


However there are some principles and approaches that varies between those two ORMs that made me cease the development of that repository component project


Don't abstract out your ORM, don't abstract things out just for the reason it will be easy for you to switch to another ORM if you don't like the performance of your current ORM. Don't add another layer (e.g., repository, or if you really need to, just add very minimal or thin layer) on top of your ORM, just let the power of your ORM flows to your application



I'm not saying that it's a futile effort to abstract out ORM differences, but there are many differences in approaches between ORMs that will make one cease the effort for doing so


when in Rome, do as the Romans do


Case in point, in order to make the domain models work on both NHibernate and Entity Framework, i.e., instead of adding foreign key property to the model, just maintain an object reference, this domain model works on both NHibernate and Entity Framework:

public class Person 
{
     public virtual int PersonId { get; set; }
     public virtual string Firstname { get; set; }
     public virtual string Lastname { get; set; }

     public virtual Country DreamCountryToTravel { get; set; }
}


However, a keen Entity Framework enthusiast shall observe: "Isn't that model expensive to populate? The DreamCountryToTravel property is an independent association, it needed be assigned with an eagerly-loaded object."

person.DreamCountryToTravel = dbContext.Countries.Find(63); // .Find eagerly loads an object from the database


However, an NHibernater would beg to disagree, "that's the right way to model the business domain, it's very OOP, and you don't need to assign an eagerly-loaded object to DreamCountryToTravel. Session.Load is efficient, it lazily loads an object, it doesn't fetch anything from the database"

person.DreamCountryToTravel = session.Load<Country>(63);


An EF enthusiasts moving to NHibernate should not (and could not) force this kind of domain model to NHibernate:
public class Person 
 {
      public virtual int PersonId { get; set; }
      public virtual string Firstname { get; set; }
      public virtual string Lastname { get; set; }
 
      
      public virtual int DreamCountryToTravelId { get; set; }
      public virtual Country DreamCountryToTravel { get; set; }
 }


EF enthusiasts only can use foreign key property in NHibernate though, but it's not the OOP way to map relational to object:
public class Person 
 {
      public virtual int PersonId { get; set; }
      public virtual string Firstname { get; set; }
      public virtual string Lastname { get; set; }
 
      public virtual int DreamCountryToTravelId { get; set; }
 }


Likewise, an NHibernater moving to Entity Framework, should not force this kind of domain model to Entity Framework, as it will only incur performance problems in Entity Framework:
public class Person 
 {
      public virtual int PersonId { get; set; }
      public virtual string Firstname { get; set; }
      public virtual string Lastname { get; set; }
 
      public virtual Country DreamCountryToTravel { get; set; }
 }


The repository pattern I've made (that works on both NHibernate and Entity Framework) have the above type of a recommended domain modeling. I readied a LoadStub method for EF (4.1 then) in my utmost hope that someday Entity Framework will offer the same functionality as NHibernate's .Load method, that EF will facilitate OOP and drop the relational/persistence concern that foreign key property is. Here's the LoadStub method:

person.DreamCountryToTravel = countryRepo.LoadStub(63);


But alas, two versions (EF 4.1 was the latest version when I made ToTheEfnhX) and later, the independent association still can only receive eagerly loaded object and it is still expensive to eagerly load an object, there's still no way to just obtain an object stub/proxy with EF. There's a way though to load stub objects only, but it's for many-to-many relationship only



And the final straw that led me to cease the development of that ORM-agnostic ToTheEfnhX repository, there's a big difference in approach between the two ORMs when fetching multiple collections. It's hard to abstract them out


If you still want to create a repository pattern/component/wrappers around your ORM, just don't pull a strawman argument to justify creating one. Here's Ayende calling out one person's strawman argument against Ayende's advocacy to not use repository:


http://ayende.com/blog/153701/ask-ayende-life-without-repositories-are-they-worth-living


Don't bindly create a pattern just for the sake of creating a pattern, you might just be reinventing the wheel if you don't realized you already have a wheel. There's no shame on not creating repository pattern when your ORM already has a repository pattern bolted-in


Avoid overengineering: http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer



I wrote this to ease out the pain of one of the teams in our company for having to transition from one ORM to another. I hope this blog reaches the whole team and make them embrace their new ORM

Will the real OOP please stand up?

Just because something is using a class doesn't mean it's doing OOP. This is not OOP:
public class Person
{
    public virtual int PersonId { get; set; }

    public virtual string LastName { get; set; }
    public virtual string FirstName { get; set; }

    public virtual int DreamCountryToTravelId { get; set; } 
}


This is OOP:
public class Person
{
    public virtual int PersonId { get; set; }

    public virtual string LastName { get; set; }
    public virtual string FirstName { get; set; }

    public virtual Country DreamCountryToTravel { get; set; }
}

Saturday, June 7, 2014

Double or triple negatives are hard to parse. Highfalutin and all that stuff

I have difficulty understanding the phrase "Not Unless." Less is negative, Un is negative, Not is negative

Sometimes I double parse the meaning of a sentence when it has the phrase "Not Unless" in it, and wondering if the speaker really intended that meaning when explaining things, or if he really just meant "Unless." It still makes me pause (giving myself enough time to parse the speaker's message) when hearing "Not Unless"



I knew well the word irregardless though, I knew that it's a wrong word. The word regardless would suffice, no need to prefix it with "ir"


I think the phrase "Not Unless" could benefit from the usage of a comma in between them. Or just use No and Unless with a well-placed pause between them



Confusing:

Q: "Are you going to make it to the party?"
A: "Not unless there are a lot of people there."



The meaning is clear:

A: "No, unless there are a lot of people there"

The answer is very clear, non-ambiguous. The answer may sound a bit blunt, but it's not ambiguous



Or avoid the double negative at all, it's instantly clear:

A: "If there are a lot of people there"



The rule of the thumb here is we should only hear the phrase "Not Unless" when something is being answered. If someone is using "Not Unless" while explaining something, the message can be confusing


Sometimes the usage of the phrase "Not Unless" is highfalutin. So there. I'm not the only one who feel that:

Question:

Is this use of 'not unless' correct?
If we travel in distant land, still uncharted on the map, and find a new mountain, can we say that we invented the mountain? Not unless we were insane.

I thought Not means we cannot, so this is really "We cannot (=Not) (say it was invented) unless we were insane.
or should i have said "not unless we are sane"?

can someone explain this to me?

Answer:

In theory it is correct but it is a horrible example of proper English, American or other former colony. The author is trying to impress him/her self with their ability to use words.



Note to self: When someone says Not Unless, mentally convert it to If. They might mean Unless though, so mentally convert it to If Not. Bummer

Friday, June 6, 2014

Geeks Shared Vocabulary For The Day: FUGLY

From a bug ticket:

Remove non-parameterized SQL from many methods used by login and also fix "FUGLY" SQL used to load up the objectives on the summary. It was using a nasty "inlist" function


Profanity is the most common programming language :D



If you are Scott Hanselman fan, you should know better:

Being generally pleasant and helpful isn't sugarcoating, it's being pleasant and helpful.



I think the rule of the thumb here, if talking in informal, e.g., around friends, colleagues or peers, it’s ok to use profanity. On conferences, presentation, it might not increase impact

Wednesday, June 4, 2014

Not in the same field/industry: Shared vocabulary == Highfalutin

To an application developers hearing two DBAs resolving an issue and using words like page splitting, extent, covering index, fill factors, sargable, archenemy and whatnot, those words are highfalutin. To a DBA hearing two application developers conversing about cascading dropdown, aggregate root, object graph, bounded context, independent association, those words are highfalutin. Words like those appears more highfalutin if one's native language is not English


If we don't have shared vocabulary or "highfalutin" word like cascading dropdown, we got to explain things in detail to someone who don't share the same set of industry vocabulary as us, we have to say this: "on this form, we need a dropdown that narrows the list of another dropdown based on the item selected from the first dropdown", see? it's too mouthful; so it's a timesaver to just use a shared vocabulary / "highfalutin" word/phrase: "on this form, we need a cascading dropdown." See? easy-peasy!

If a word is not used on a daily basis, yet you wanted to introduce it to others, the reception on that word is that it is too highfalutin, big word

For debaters, politicians and whathaveyou, the word strawman is not highfalutin, they know the meaning of strawman when one of them say that the other one is pulling an strawman argument and should refrain from doing so


When there are important matters that are being discussed, and one just conveniently cite the person #2 use of highfalutin word even the person #2 just used one "highfalutin" word throughout the whole discourse, person #2 might reply with "please don't bikeshed!", but alas! person #2 will be reluctant to say that since he's already labeled of using highfalutin word. See? almost every words are highfalutin if one can't be bothered to learn the meaning of a handy word, er.. "highfalutin" word


Shared vocabulary is important, it saves us the hassle of explaining things in length when some things related to that vocabulary comes up very often or shall come up again during a conversation or discourse


Having said that, here are some four of the shared vocabulary (or highfalutin if you may) engineers could use with each other without being sneered at as being too highfalutin:


1. Bikeshedding: Technical disputes over minor, marginal issues conducted while more serious ones are being overlooked.

If someone tend to dwell on the syntax(e.g., suggesting to use string.Empty instead of letting the code use "") of the code instead of the code's functionality, go ahead and say "Please don't bikeshed, it's ok not to use string.Empty, let's focus on the functionalities"


2. Leaky abstraction: In software development, a leaky abstraction is an implemented abstraction where details and limitations of the implementation leak through.

jQuery is an abstraction layer that makes all browsers behaves and looks the same API-wise. Example, jQuery's .html is consistent on all browsers; though one can use .innerHTML API directly instead of using jQuery's .html, it's not a good idea to do so, some browsers has buggy implementation and/or not consistent with other standards-conforming browsers

So if someone is unwittingly or deliberately leaking an abstraction, e.g., using .innerHTML, go ahead and tell him "Please don't leak the abstraction, use jQuery's .html"


3. SARGable: In relational databases, a condition in a query is said to be sargable if the DBMS engine can take advantage of an index to speed up the execution of the query.

The DBA looking at your query and said "this condition is not sargable, please re-arrange the expression." Comply then


4. Strawman: Misrepresenting someone's argument to make it easier to attack

If someone is trying to undermine your point by using something far from the context of your point, you can remind them not to use strawman argument

Example: After Will said that we should put more money into health and education, Warren responded by saying that he was surprised that Will hates our country so much that he wants to leave it defenseless by cutting military spending.

Tip: If you hang around slashdot forum, you'll often encounter geeks opposing strawman arguments



Shared vocabulary prevents ambiguities in communication

Sunday, June 1, 2014

There are developers that are too childish and bikesheddin'

"I simply want to select the last 4 entries from a table, not too much to ask is it really?!!
You would think M$ would have covered this one by now!!" – http://stackoverflow.com/questions/10634855/opposite-of-select-top

Bikeshedding definition: https://en.wikipedia.org/wiki/Parkinson's_law_of_triviality

SELECT BOTTOM with Linq

Added Last/LastOrDefault functionality in our custom ORM, so we can now do things in idiomatic way, e.g., getting the last country alphabetically.

Non-idiomatic, we are getting the last country, yet we are using FirstOrDefault:
var lastCountry = countryDao.Context.OrderByDescending(x => x.CountryName).FirstOrDefault();

Idiomatic way to get the last row:
var lastCountry = countryDao.Context.OrderBy(x => x.CountryName).LastOrDefault();


Both of the codes above resolves to SELECT TOP ORDER BY DESC, as there's no SELECT BOTTOM in SQL:
SELECT TOP 1 c.CountryId, c.CountryName, c.Population
FROM Countries c
ORDER BY c.CountryName DESC


I naturally assumed NHibernate and Entity Framework supports Last/LastOrDefault, just tried them now, but they haven't supported it yet