35

As developers, we often face the challenge of balancing meaningful variable names with code readability. Long, descriptive names can make code harder to read, while short names may lack context. For example:

# Long but descriptive
lowest_integer_allowed_to_set_as_upper_bound_in_game_mode = 10

# Short but less clear
lowest_bound = 10

I've been considering a potential solution: allowing developers to attach descriptive metadata directly to variables. This could look something like:

int lowest_bound @description("The lowest integer allowed to set as the upper bound in game mode") = 10;

IDEs could then display this description when hovering over the variable, maintaining readability while preserving context.

Questions:

  1. Are there existing programming languages or IDEs that support this kind of feature?
  2. How does this idea compare to existing solutions for managing the trade-off between descriptive naming and code readability (e.g., comments, documentation strings)?
  3. Could this approach effectively improve code maintainability and developer productivity?
0

10 Answers 10

41

Why doesn't it exist?

The direct answer here is that this isn't technically impossible, no one has just been sufficiently bothered enough by it to create a field-spanning standard that everyone can and is willing to actively make use of.

If you're thinking about this on an IDE level, this would only maintain compatibility for people using the same IDE, which isn't great. On the language level, some implementations of this actually do exist, such as C#'s documentation comments.

Image

From experience though, this documentation is hardly used unless you hit the perfect storm of a non-trivial bit of code, a developer who is aware of this from the perspective of other readers and who is keen on documenting things for future readers.


Would it help?

However, I do want to point out that human behavior tends to work the opposite way.

When you make things safer, humans tend to take bigger risks. Life is a series of risk/reward challenges, and while different people set the bar at different heights for what risk they're willing to engage in, a given person tends to keep the bar where it is. If you make things safer, they'll do something bigger that now yields the same risk (the added safety offsets the increased risk).
One common example is that introducing the airbag into cars has dramatically reduced driver/passenger harm, but at the same time it has increased the amount of accidents and, by extension, pedestrian harm (i.e. people outside of the offending vehicle). Making cars safer makes it safer to engage in risky driving.

More so than increasing the tooling around documenting complex codebases, we should be focusing on reducing the complexity in the first place. When you give people more documentation tools, they are likely to decrease their efforts in reducing complexity, "because the documentation explains how it works".

Using C#s documentation comments as an example, it makes sense to document e.g. a library's public methods, because there is an inherent expectation that an "outsider" to the library needs to integrate the library into their own work.

But, by contrast, a private field or variable? That's solely used by the developer who owns the entire scope in which it lives. Local implementations should never reach the level of complexity that warrants the effort of explicitly documenting these kinds of things. That just suggests that you need to break down your logic into smaller, more easily digestible steps.


Would it be a productive solution?

And even then, if we assume your scenario, how can this not already be solved by a simple line comment?

# The lowest integer allowed to set as the upper bound in game mode
lowest_bound = 10

What would be the added benefit of your proposal?

I think this implies that you're dealing with logic that is monolithic in nature to the point of not fitting on the screen, which is why you're asking for a documentative feature that could carry that information to where you need it. You seem to imply this when you say:

IDEs could then display this description when hovering over the variable, maintaining readability while preserving context.

Based on that inference, you're proving my point. You're trying to document your way out of code that is needlessly complex. Instead, dedicate your effort towards reducing the complexity so that the code no longer needs documentation to make sense of in the first place.

9
  • 17
    "From experience though, this documentation is hardly used" [CITATION NEEDED]. Documentation comments are wildly used at least in Java and are tremendously helpful in my experience. I am always disappointed when working in C# how bad the documentation comments are...
    – Polygnome
    Commented Aug 12 at 8:17
  • 5
    "When you make things safer, humans tend to take bigger risks." For anyone who's curious, the term for this is risk compensation. Commented Aug 12 at 14:01
  • 4
    @Polygnome: "Documentation comments are wildly used" [CITATION NEEDED]. Witty retort aside, my statement is made based on over a decade's worth of experience, admittedly mostly in the .NET ecosystem but the core issue is one of developer attitude/care factor rather than specific language implementation of the documentation feature. Does it get used? Sure. To the degree that OP is suggesting their proposed feature be used? Absolutely not.
    – Flater
    Commented Aug 12 at 23:11
  • 6
    This answer is pretty opinionated. "You are trying to document your way out of code that is needlessly complex", "From experience though, this documentation is hardly used", "the added safety offsets the increased risk". While these are reasonable opinions, good documentation support is useful. Either it makes good code even better or it makes overly complex code at least understandable. Also, I've had plenty of cases where complex code was the only solution, as the underlying problem was complex. I'd pray my predecessor provided good documentation, and tried to do likewise for my successor.
    – HolKann
    Commented Aug 13 at 9:47
  • 2
    @Flater I fully believe you that its not wildly used in C#, because honestly, both MS as well as 3rd party docs are just not good. But in my 2 decades with Java, I can tell you that its widely used and very effective. It think it comes down to culture. Oracle does a good job with doing good documentation, and so 3rd party libs are held to a higher standard es well. using C# as an example for how it would inevitably turn out in other languages seems a bit short-sighted, or presumptuous.
    – Polygnome
    Commented Aug 14 at 10:11
39

TLDR

Decomposition makes names shorter. Do not fight symptoms, solve underlying problem instead.

Scope is important

Naming is the hardest problem, not because long names are not readable, but because they are not useful when used in a proper scope. Naming and decomposition (and scoping which is dictated by decomposition) are both results of problem analysis and conceptualization. Names will remain unclear and verbose until the problem is well-conceptualized and decomposed.

The long name in the original example is an example of god object antipattern.

Consider validation of Game state in the original example.

if (speed_max < lowest_integer_allowed_to_set_as_upper_bound_in_game_mode || speed_max > highest_integer_allowed_to_set_as_upper_bound_in_game_mode) {
    render_out_of_range()
}

... Repeat for speed_min

On this level of abstraction, all variables are present in a global scope and have to share namespace.

Now consider higher level of abstraction:

struct Range {
    int min;
    int max;
}
...
GameMode game_mode(speed=ConfigurableRange(Range(0, 5), 3, Range(10, 15), 12))
...
if (!game_mode.speed.matches(speed_range)) {
    render_out_of_range()
}

Here we introduce concepts or ranges, acceptable and default values, and enforce various contacts between them. The names are shorter, because of narrow scope and consistent abstraction level.

Qualifiers are not visible from other abstraction levels

In modern languages, names of variables are shorter, because they share smaller namespace and level of abstraction and are context specific. It makes no sense for a field of Range structure to have "bound" suffix, because we know that Range has two bounds. It does not have "speed" qualifier because speed is higher level of abstraction. It does not have type information, because type is derived from typesystem or type parameter. It does not have "allowed" qualifier, because of predicate nature of Range. Etc...

Do not fix symptoms, solve root cause

Introduction of short names with long descriptions would discourage problem decomposition and layering and encourage low level solutions. This is fine for system programming, but is unacceptable everywhere else. Spend time on decomposition, instead of writing a low level documentation.

1
  • 4
    This. This is the real answer to the question behind the question. Commented Aug 12 at 12:27
28
  1. Java and C# at least have this sort of feature. Javadoc is the system for it in the Java context, Documentation comments in C# context. Indeed, that’s how IDEs provide on-hover info at all.
  2. Generally speaking, this feature is less useful than good variable naming. It doesn’t immediately show up at callsites. It requires IDE awareness to actually display the information. And 30 years of experience shows that programmers rarely look at the descriptions.
  3. No, since it’s already a relatively well known idea. Beyond that, much of the benefit of improving variable names isn’t adding context in something like a description, but simplifying the code itself when you realize that it’s hard to name things.
2
  • 5
    A decent proportion of variables tend to be function parameters, so python docstrings also accomplish this.
    – user46745
    Commented Aug 12 at 6:48
  • To add to @user46745's comment: the usual documentation tools (e.g. Sphinx) also accept docstrings for global names and object attributes. This leaves local names, which should not need such extra information to carry around. They can get additional information in a comment.
    – BlackJack
    Commented Aug 14 at 12:35
12

It's a good question, and some IDEs do have the functionality you suggest, but virtually all programming languages and IDEs have the simple ability to add comments like so:

// The lowest integer allowed to set as the upper bound in game mode

int lowest_bound = 10;

This approach tends to work as well as can be, whenever there is something strange about a local variable so that its role needs considerable explanation.

The problem in practice with insufficient variable names, is often that the programmer didn't spend enough time (or have enough skill and vocabulary) to choose a sensible name.

This problem - of lack of time or skill - often spills over into any longer, more wordy description anyway, which is then equally unclear or hard to parse.

The context might also consist of a confusing and jarring combination of concepts, or poor correspondence between the structure of the code and how the programmer is liable to organise the conceptual structure in their minds, seeming to require textual explanation that would be less necessary if these other mistakes were just avoided in the first place.

Again, a programmer who makes a confusing mess of the structure, is unlikely to then speak elegantly in a textual commentary which exists only to undo the damage of their initial mistake. Because the cause of the initial mistake was often an inability to think or communicate clearly, or even to perceive the flaw.

This is often why programmers end up wanting to rewrite their own code after a second reading later, because once their mind has gone a bit cold and they're seeking to recollect by actually reading the code (rather than writing the code from an understanding that is already fully in mind), it then becomes more obvious how poorly the code is speaking back and guiding their minds.

I add small commentary descriptions to locals only rarely, typically when I don't fully control the naming scheme itself - for example, when a local represents a database field, and when the database design isn't great. It's a sticking plaster for the occasional infelicity - not a good practice that should be applied to all locals.

6

As detailed by the previous answers, there are both IDEs and Programming languages do have support for this.

Support comes in three general categories:

  1. Documentation in the code that must be interpreted by the IDE / Compiler / Consumer, these could be interpreted at runtime is you write the code to interpret them
  2. You can define your own Type definitions that can enforce some constraints at compile time, and others at Runtime
  3. Direct support in the language runtime

I'll get to the specific support scenarios, but lets deal with the biggest issue that you haven't described... Why?

How important is it to know all of this information about a variable: lowest_integer_allowed_to_set_as_upper_bound_in_game_mode which is effectively including these metadata:

  • type: integer
  • name: lowest upper bound
  • comment: lowest value that can be set in game mode

In terms of reading the code, the type itself is not always as useful as you think, the intent of the variable however is. A well designed class structure should be able to convey most of the intent from the name and structure alone, however it is useful to include comments if you think the intent is still ambiguous.

Many IDEs already provide this support natively, type is a common standard feature however most languages will support a form of structured comments that can be parsed form the source code by a separate process, this makes it less a feature of the language itself and more of a convention and tools that IDEs can use. The following is a standard Doc Comment in C#:

/// <summary>The lowest integer allowed to set as the upper bound in game mode</summary> 
int lowest_bound = 10;

The Visual Studio IDE shows these summary comments in a tooltip when you hover over the member field/property reference: Intellisense example

The major caveat to this is that it only works on member level definitions or classes themselves, not on local variables within methods. This is due to the way the comments are compiled and is a generally accepted limitation within methods because you can see and use standard code comments to document in these cases.

There is also JSDoc for javascript that is very similar, however it is possible to document local variables in the function doc comment, makes things a little clumsy to maintain but it can work

One way to get around the local variable documentation issue is to define a separate class to hold the variable values, this is not always practical but can be especially useful if you need to pass these variables around or need to defined them frequently

public class Options
{
    /// <summary>The lowest integer allowed to set as the upper bound in game mode</summary> 
    int lowest_bound = 10;
}

example of options class

How does this idea compare to existing solutions for managing the trade-off between descriptive naming and code readability (e.g., comments, documentation strings)?

Well this IS using comments instead of going over the top with naming conventions.

Could this approach effectively improve code maintainability and developer productivity?

As a C# developer, I find that this gives us a fluent way to document the code (at the source) while the IDE makes it easier for the developer to discover the comments. Even for local variables, when we need to know more the convention is to right click and goto the definition of the variable as the first destination for documentation.

It is undoubtably a key productivity feature of Visual Studio and one of the reasons that some people switch over to .Net from java.

It is great for maintenance and team productivity because this is a standard feature of the language that is supported in all the major IDEs so old and new developers coming into a project should all be familiar with this, you do not need to develop or follow a separate standard for a given project or dev team.

The feature itself does not however help with speed-reading of the code because you have to move the mouse to hover over the variable. To improve reading efficiency, you should implement more descriptive names but don't go over the top.

  • Or if you think you need to, just add a comment in the code!

Apps Hungarian is not a bad style of convention if you feel the need to overshare using concise notation, but do not include the actual type of the variable in the name, that is largely irrelevant to understanding the context and intent of the code.

5

Looks like you're programming in Python, so to start with that as an example: There's absolutely something like this! They're called "docstrings" (short for documentation strings), because that's pretty much what they are.

lowest_bound = 0
"""
Lowest integer allowed to set as upper bound in game mode
"""

You can do a lot more than just adding a simple text description to a variable, too:

def add(a, b): 
    """
    Function that adds 2 values
    :param a: The first value to add
    :param b: The second value to add
    :returns: The sum, concatonation, or whatever the + operator did
    """
    return a + b

Many IDEs, including JetBrains PyCharm, will respect this and show this information when you hover over symbols - in fact, that's how you get the hints when you hover over symbols from modules. (Many also respect Python's type hints and warn you if you've used the wrong type somewhere!)

In more general terms, many languages have something similar to this, and many IDEs leverage it. C# has XML documentation comments, JavaScript has JSDoc, etc.

3

Some languages such as Java, C#, Python and others already have built-in capabilities for this: respectively, Java's JavaDoc comment format, C#'s documentation comment format, and the various docstring comment formats for interpreted languages.

For a number of other languages such as C, C++, VHDL and others, an add-on tool to do this already exists - it's called Doxygen. This gives a standard format of comments within your code for describing variables, functions, classes, data types and files.

Initially this was intended as a way to automatically generate human-readable documentation from code, solving the common problem of a separate data dictionary describing variables becoming out of date.

Regardless of whether you choose to auto-generate documentation though, these documentation formats still give a standard way to document your code, and are frequently used solely for that reason. Plugins exist for many IDEs which can parse those comments.

Some years after the fact, it is not completely clear where this concept originated. Java was first released in 1995 and Doxygen was first released in 1997, so it seems likely Doxygen was a copy of this feature for C/C++, especially since the comment formats are almost identical. It is worth noting though that many larger organisations had in-house commenting formats already by this point, so this was not a new concept at the time. The primary achievement was standardising formats across industry.

0
2

They have, by moving to OOP. There’s all kinds of tools for adding meta data to class values from xml markup to attributes and even whether they are properties or not.

But it sounds like you are asking about local variables, and again, they have, with things like local and anonymous functions and adding meta data to their parameters.

What they haven’t done is give the same ability to plain ole local variables, and frankly that isn’t done because the scope of the variable should only be a few lines of code, a dozen or so at most. And at that level, you don’t need the extra meta data to know what it does, and it doesn’t do any good anywhere else.

A local variable may need a comment, but it doesn’t need to be formalized beyond that, because it’s not of interest beyond its (hopefully very limited) scope.

1

Been there, done that.

In a language called MDL (aka MUDDLE) it was possible to associate any object with any other object, and give the association a name, such as "comment". This means that the comment could be a function instead of a string, if that seemed useful.

This carried some overhead, because this type of comment was available at run time, and not only in the source code. Some people used this kind of metadata (if you can call a function metadata) to include debugging aides with certain kinds of objects.

MDL was built at project MAC, MIT in the 1971-1972 time frame. It was a lisp like language that supported datatypes and arrays. I was on the team that designed and built MDL.

1

To add an example language + environment that does support this: Factor!

If you'll forgive my non-default prompt (🦖):

🦖 SYMBOL: lowest-bound
🦖 10 lowest-bound set
🦖 HELP: lowest-bound { $description "The lowest integer allowed to set as the upper bound in game mode" } ;

Then if you type lowest-bound in the "listener" (GUI/REPL/semi-IDE) and hit ctrl-h, the documentation browser pops up and shows you that description.


EDIT: This was marked as unclear, so I will try to clarify.

This answer is a response to question 1:

Are there existing programming languages or IDEs that support this kind of feature?

"this kind of feature" being:

. . . allowing developers to attach descriptive metadata directly to variables.

Yes there are, and one of these is Factor.

In Factor, a dynamic variable is a key-value pair in a namespace map/dictionary/assoc, and its key is (generally) a symbol.

A symbol pushes itself on the stack when executed.

Generally it is a variable name. Like most things in Factor, it is a "word," and words can and do have all sorts of properties themselves, which can include their documentation.

Revisiting the hypothetical form from the original question:

int lowest_bound @description("The lowest integer allowed to set as the upper bound in game mode") = 10;

Here's a look at all the metadata around a symbol in Factor:

🦖 SYMBOL: lowest-bound
🦖 10 lowest-bound set
🦖 lowest-bound inspect

This prints a table:

IN: scratchpad SYMBOL: lowest-bound
0 hashcode      -549872870026224836
1 name          "lowest-bound"
2 vocabulary    "scratchpad"
3 def           [ \ lowest-bound ]
4 props         H{ { "inline" t } { "dependencies" ~array~ } { "declared-effect"...
5 pic-def       f
6 pic-tail-def  f
7 sub-primitive f

Right now props is a hashmap (assoc) with three entries.

But if we define documentation for the word:

🦖 HELP: lowest-bound { $description "The lowest integer allowed to set as the upper bound in game mode" } ;

the props hashmap gains a fourth entry, "help":

🦖 lowest-bound "help" word-prop .
{
  {
    $description
    "The lowest integer allowed to set as the upper bound in game ..."
  }
}

If you type lowest-bound help and hit enter, it opens the documentation viewer with the description we added for lowest-bound. This will also happen if we instead type lowest-bound and hit the help shortcut (ctrl-h), or if we push it (type lowest-bound and hit enter), then click on the word.

screenshot of documentation viewer showing lowest-bound description

2
  • 1
    Relevant languages please :P
    – qwr
    Commented Aug 13 at 3:38
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Aug 14 at 18:18

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