Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm modeling a chemical system, and I'm having problems with naming my elements / items within an enum.

I'm not sure if I should use:

  • the atomic formula
  • the chemical name
  • an abbreviated chemical name.

For example, sulfuric acid is H2SO4 and hydrochloric acid is HCl.

With those two, I would probably just use the atomic formula as they are reasonably common.

However, I have others like sodium hexafluorosilicate which is Na2SiF6.

In that example, the atomic formula isn't as obvious (to me) but the chemical name is hideously long: myEnum.SodiumHexaFluoroSilicate. I'm not sure how I would be able to safely come up with an abbreviated chemical name that would have a consistent naming pattern.

There are a few problems that I'm trying to address through naming the enum elements.
The first is readability, with the longer names presenting an issue.
The second is ease of picking up the code for new maintainers, and here the shorter names present an issue.
The next issue is the that business owners usually refer to the full chemical name, but not always. The "mouthful" chemicals are referred to by their formula.
The final concern is making sure it's consistent. I don't wan't a mixed naming convention as it will be impossible to remember which to use.

From a maintenance point of view, which of the naming options above would you prefer to see and why?


Note: Everything here below the line is supplementary | clarifying material. Please don't get bogged down in it. The main question regards naming the awkward objects.

Atomic Option

public myEnum.ChemTypes
{  
   H2SO4,
   HCl,
   Na2SiF6
}

Chemical Name Option

public myEnum.ChemTypes
{
   SulfuricAcid,
   HydrochloricAcid,
   SodiumHexafluorosilicate  
}

Here are some additional details from the comments on this question:

  • Audience for the code will be just programmers, not chemists.
  • I'm using C#, but I think this question is more interesting when ignoring the implementation language.
  • I'm starting with 10 - 20 compounds and would have at most 100 compounds, so I don't need to worry about every possible compound. Fortunately, it's a fixed domain.
  • The enum is used as a key for lookups to facilitate common / generic chemical calculations - which means that the equation is the same for all compounds but you insert a property of the compound to complete the equation.

    • For example, Molar mass (in g/mol) is used when calculating the number of moles from a mass (in grams) of the compound. FWIW, Molar Mass == Molar Weight.
    • Another example of a common calculation is the Ideal Gas Law and its use of the Specific Gas Constant

A sample function might look like:

public double GetMolesFromMass(double mass_grams, myEnum.ChemTypes chem)
{
  double molarWeight = MolarWeightLookupFunctionByChem(chem); //returns grams / mole
  double moles = mass / molarWeight;  //converts to moles

  return moles;
}

//Sample Call:
myMoles = GetMolesFromMass(1000, myEnum.ChemTypes.Na2SiF6);
//*or*
myMoles = GetMolesFromMass(1000, myEnum.ChemTypes.SodiumHexafluorosilicate);
public double GetSpecificGravity(myEnum.ChemTypes chem, double conc)
{
  //retrieves specific gravity of chemical compound based upon concentration
  double sg = SpecificGravityLookupTableByChem(chem, conc);  
}

So the enum of the compound name is used as a key and to provide consistency in referencing the compound with the related functions.

share|improve this question
7  
why do they need to be enums? there are infinite amount of possible compounds so you are never going to be able to set them all –  ratchet freak Dec 19 '12 at 16:06
3  
As a programmer, not chemist, I find that Na2SiF6 and sodium hexafluorosilicate are equally obscure. The former is shorter to type and is most likely to pass weird not-more-than-40-chars-by-identifier coding rules. –  mouviciel Dec 19 '12 at 16:30
5  
As a programmer, I personally think that Sodium is going to roll off my fingers faster than Na2 - words tend to flow easier for me when typing (I hate Hungarian notation for this reason). –  Drake Clarris Dec 19 '12 at 16:48
5  
They shouldn't be enum values, they should be instances of Substance with whatever properties they need. –  AakashM Dec 19 '12 at 16:50
2  
@GlenH7: just read your question on "meta". I think the real problem here for some folks here is "why do chemical names have to be in the code at all"? Having those names only as some form of data would avoid cluttering your code with very long names, and you could choose the names just like the user of your system prefers, independently from what a developer might think about them. That would delegate the naming responsibility to the user and avoid your problem completely. –  Doc Brown Dec 21 '12 at 11:40
show 8 more comments

6 Answers

up vote 9 down vote accepted

When I started rewriting my current project from spaghetti into reasonable code, I was faced with the same problem. My problem domain is medical, and rather than use names like "ETCO2" and "SPO2" for my enums I used the full English names.

On the one hand, it was very useful to have English names when I was new to the problem domain. On the other hand, now that I've been working with these terms for a year I find that the full English names are far too verbose and I'm familiar enough with the terms that I'd much prefer to use the abbreviations.

My advice would be to use the atomic formula and include a comment by each enum value that gives its full name, on the assumption that anyone who looks at your code will either be a) a chemist, or b) working on the code long enough that they naturally become familiar with the formulae.

share|improve this answer
1  
+1: Besides, one could always look up "ETCO2" or "Na2SiF6" and be done with it. –  Steve Evers Dec 19 '12 at 20:21
add comment

Who is the audience for the code? Will chemists be using the Enums, or just programmers without specific domain training in chemistry?

If chemists will be using the code, ask them. Very likely they will prefer the abbreviated symbols, as they can readily recognize them. If general-knowledge programmers will be using these identifiers on behalf of the chemists, I think it's better to go with the English-like versions.

share|improve this answer
    
it will be just programmers, not chemists –  GlenH7 Dec 19 '12 at 16:16
1  
or add the translation in the documentation of each enum –  ratchet freak Dec 19 '12 at 16:17
add comment

No reason not to combine "all the above."

The problem with the full names is it will be tedious to type, the problem with the symbol names is lack of meaning.

So, create constants of the values with the full name. Then create defines associated with the constant. You can easily then create newer,shorter defines as you become more familiar with the meaning of the abbreviation.

const int SodiumHexaFluoroSilicate = 16893859;   
const float Gold = 196.966569;

#define SoduimSilicate SodiumHexaFluoroSilicate 
#define F6Na2Si SodiumHexaFluoroSilicate 
#define au Gold 
share|improve this answer
    
I used some borked C code sample ... I think it should translate to C# easily enough. –  Daniel Dec 19 '12 at 16:57
    
I'm not as worried about a particular implementation which is why I didn't specify C# in my question. And I liked your suggestion from a C point of view. The C# Description tag from System.ComponentModel is an elegant way to add the descriptor though. I was more interested in the broader answer to the question over a particular implementation. –  GlenH7 Dec 19 '12 at 17:11
add comment

When you design any application, you should separate the data from the program logic. Are the chemical compounds really part of the program logic and not rather the data the program logic is operating on?

When they are data, it would be much better to not treat them as enums but rather read their names and properties from a configuration file and store them in a data structure. That would also make maintainance a lot easier. When one needs to add new compounds, or finds an error in the properties of one, they can just edit the configuration file.

share|improve this answer
1  
+1 @GlenH7 it'd help if you could explain why specific chemical compounds are part of the code, especially after you've said that "the equation is the same for all compounds." –  Caleb Dec 19 '12 at 17:15
1  
@GlenH7: Still no reason why the chemicals aren't just data. Several posters are helpfully telling you not to use an enum. I certainly wouldn't. –  kevin cline Dec 19 '12 at 22:24
1  
@kevincline & caleb (and everyone else actually), I have created a meta question asking for help on how to structure this question and the enum aspect of it. I would appreciate your feedback. –  GlenH7 Dec 19 '12 at 23:06
3  
Well, when someone comes to you with a knive stuck in his head, and he asks you to look at the splinter in his hand, it's hard to concentrate on that. –  Philipp Dec 19 '12 at 23:08
1  
@Caleb - Question updated to better clarify the use of the enum. –  GlenH7 Dec 20 '12 at 1:10
show 5 more comments

This seems like it could be better implemented as a class that can expand and translate based on the developers' needs. Below is some sample C# I came up with to allow for a few well-known defined chemicals (as properties) and then queryable stores (via Add and Get methods). You can also extend pretty easily to have your molar mass and other chemical properties available.

public interface IChemical
{
    string AtomicFormula
    {
        get;
    }

    string ChemicalName
    {
        get;
    }

    string AbbreviatedChemicalName
    {
        get;
    }
}

public sealed class Chemical : IChemical
{
    private static readonly IChemical h2so4 = new Chemical("H2SO4", "sulfuric acid", "sulf. acid");

    private static readonly IChemical hcl = new Chemical("HCl", "hydrochloric acid", "hydro. acid");

    private static readonly IDictionary<string, IChemical> chemicalsByAtomicFormula = new Dictionary<string, IChemical>();

    private static readonly IDictionary<string, IChemical> chemicalsByChemicalName = new Dictionary<string, IChemical>();

    private static readonly IDictionary<string, IChemical> chemicalsByAbbreviatedChemicalName = new Dictionary<string, IChemical>();

    private readonly string atomicFormula;

    private readonly string chemicalName;

    private readonly string abbreviatedChemicalName;

    static Chemical()
    {
        chemicalsByAtomicFormula.Add(h2so4.AtomicFormula, h2so4);
        chemicalsByChemicalName.Add(h2so4.ChemicalName, h2so4);
        chemicalsByAbbreviatedChemicalName.Add(h2so4.AbbreviatedChemicalName, h2so4);
        chemicalsByAtomicFormula.Add(hcl.AtomicFormula, hcl);
        chemicalsByChemicalName.Add(hcl.ChemicalName, hcl);
        chemicalsByAbbreviatedChemicalName.Add(hcl.AbbreviatedChemicalName, hcl);
    }

    public Chemical(string atomicFormula, string chemicalName, string abbreviatedChemicalName)
    {
        if (string.IsNullOrWhiteSpace(atomicFormula))
        {
            throw new ArgumentException("Atomic formula may not be null or whitespace.", "atomicFormula");
        }

        if (string.IsNullOrWhiteSpace(chemicalName))
        {
            throw new ArgumentException("Chemical name may not be null or whitespace.", "chemicalName");
        }

        if (string.IsNullOrWhiteSpace(abbreviatedChemicalName))
        {
            throw new ArgumentException("Abbreviated chemical name may not be null or whitespace.", "abbreviatedChemicalName");
        }

        this.atomicFormula = atomicFormula;
        this.chemicalName = chemicalName;
        this.abbreviatedChemicalName = abbreviatedChemicalName;
    }

    public static IChemical H2SO4
    {
        get
        {
            return h2so4;
        }
    }

    public static IChemical HCl
    {
        get
        {
            return hcl;
        }
    }

    public string AtomicFormula
    {
        get
        {
            return this.atomicFormula;
        }
    }

    public string ChemicalName
    {
        get
        {
            return this.chemicalName;
        }
    }

    public string AbbreviatedChemicalName
    {
        get
        {
            return this.abbreviatedChemicalName;
        }
    }

    public static void AddChemical(IChemical chemical)
    {
        if (chemical == null)
        {
            throw new ArgumentNullException("chemical", "chemical may not be null");
        }

        if (chemicalsByAtomicFormula.ContainsKey(chemical.AtomicFormula))
        {
            return;
        }

        chemicalsByAtomicFormula.Add(chemical.AtomicFormula, chemical);

        if (chemicalsByChemicalName.ContainsKey(chemical.ChemicalName))
        {
            return;
        }

        chemicalsByChemicalName.Add(chemical.ChemicalName, chemical);

        if (chemicalsByAbbreviatedChemicalName.ContainsKey(chemical.AbbreviatedChemicalName))
        {
            return;
        }

        chemicalsByAbbreviatedChemicalName.Add(chemical.AbbreviatedChemicalName, chemical);
    }

    public static IChemical GetChemicalByAtomicFormula(string atomicFormula)
    {
        if (string.IsNullOrWhiteSpace(atomicFormula))
        {
            throw new ArgumentException("Atomic formula may not be null or whitespace.", "atomicFormula");
        }

        IChemical chemical;

        return chemicalsByAtomicFormula.TryGetValue(atomicFormula, out chemical) ? chemical : null;
    }

    public static IChemical GetChemicalByChemicalName(string chemicalName)
    {
        if (string.IsNullOrWhiteSpace(chemicalName))
        {
            throw new ArgumentException("Chemical name may not be null or whitespace.", "chemicalName");
        }

        IChemical chemical;

        return chemicalsByChemicalName.TryGetValue(chemicalName, out chemical) ? chemical : null;
    }

    public static IChemical GetChemicalByAbbreviatedChemicalName(string abbreviatedChemicalName)
    {
        if (string.IsNullOrWhiteSpace(abbreviatedChemicalName))
        {
            throw new ArgumentException("Abbreviated chemical name may not be null or whitespace.", "abbreviatedChemicalName");
        }

        IChemical chemical;

        return chemicalsByAbbreviatedChemicalName.TryGetValue(abbreviatedChemicalName, out chemical) ? chemical : null;
    }
}

you can add new chemicals like such:

        Chemical.AddChemical(new Chemical("Na2SiF6", "sodium hexafluorosilicate", "sod. hex.flu.sil."));

and get the other bits as such:

        Console.WriteLine(Chemical.GetChemicalByChemicalName("sulfuric acid").AtomicFormula);
share|improve this answer
    
Thanks for the answer, and I have updated my question to be a bit more clear in what I'm targeting. I'm not so worried about getting the name of the chemical compound as I am with accessing its properties from various tables and such. I have an open meta question on whether or not I should add in the enum discussion or to break that into a separate Q. –  GlenH7 Dec 20 '12 at 1:08
add comment

If you are using C# with Visual Studio then I'd use the longer names. As a developer, I find them more readable and if Intellisense is working, you wouldn't need to type out the whole thing anyway.

share|improve this answer
1  
thank you for the answer, and I would encourage you to expand upon it. I would focus on the contrast to Ant's answer where he's recommending the opposite. –  GlenH7 Dec 20 '12 at 1:12
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.