Why do programming languages allow shadowing/hiding of variables and functions?

Many of the most popular programming languges (such as C++, Java, Python etc.) have the concept of hiding / shadowing of variables or functions. When I’ve encountered hiding or shadowing they have been the cause of hard to find bugs and I’ve never seen a case where I found it necessary to use these features of the languages.

To me it would seem better to disallow hiding and shadowing.

Does anybody know of a good use of these concepts?

Update:
I’m not refering to encapsulation of class members (private/protected members).

4

If you disallow hiding and shadowing, what you have is a language in which all variables are global.

That’s clearly worse than allowing local variables or functions that may hide global variables or functions.

If you disallow hiding and shadowing, AND you attempt to “protect” certain global variables, you create a situation where the compiler tells the programmer “I’m sorry, Dave, but you can’t use that name, it is already in use.” Experience with COBOL shows that programmers almost immediately resort to profanity in this situation.

The fundamental issue is not hiding/shadowing, but global variables.

21

Does anybody know of a good use of these concepts?

Using accurate, descriptive identifiers is always a good use.

I could argue that variable hiding doesn’t cause many bugs since having two very similarly named variables of the same/similar types (what you’d do if variable hiding was disallowed) is likely to cause just as many bugs and/or just as severe bugs. I don’t know if that argument is correct, but it’s at least plausibly debatable.

Using some kind of hungarian notation to differentiate fields vs local variables gets around this, but has its own impact on maintenance (and programmer sanity).

And (perhaps most likely the reason that the concept is known of in the first place) it’s far easier for languages to implement hiding/shadowing than to disallow it. Easier implementation means that compilers are less likely to have bugs. Easier implementation means that the compilers take less time to write, causing earlier and broader platform adoption.

5

Just to ensure we’re on the same page, method “hiding” is when a derived class defines a member of the same name as one in the base class (which, if it is a method/property, is not marked virtual/overridable), and when invoked from an instance of the derived class in “derived context”, the derived member is used, while if invoked by the same instance in the context of its base class, the base class member is used. This is different from member abstraction/overriding where the base class member expects the derived class to define a replacement, and from scope/visibility modifiers that “hide” a member from consumers outside the desired scope.

The short answer to why it’s allowed is that not to do so would force developers to violate several key tenets of object-oriented design.

Here’s the longer answer; first, consider the following class structure in an alternate universe where C# doesn’t allow member hiding:

public interface IFoo
{
   string MyFooString {get;}
   int FooMethod();
}

public class Foo:IFoo
{
   public string MyFooString {get{return "Foo";}}
   public int FooMethod() {//incredibly useful code here};
}

public class Bar:Foo
{
   //public new string MyFooString {get{return "Bar";}}
}

We want to uncomment the member in Bar, and by so doing, allow Bar to provide a different MyFooString. However, we cannot do so because it would violate out alternate-reality prohibition on member hiding. This particular example would be rife for bugs and is a prime example of why you might want to ban it; for instance, what console output would you get if you did the following?

Bar myBar = new Bar();
Foo myFoo = myBar;
IFoo myIFoo = myFoo;

Console.WriteLine(myFoo.MyFooString);
Console.WriteLine(myBar.MyFooString);
Console.WriteLine(myIFoo.MyFooString);

Off the top of my head, I’m actually not sure whether you’d get “Foo” or “Bar” on that last line. You’d definitely get “Foo” for the first line and “Bar” for the second, even though all three variables reference exactly the same instance with exactly the same state.

So, the language’s designers, in our alternate universe, discourage this obviously bad code by preventing property hiding. Now, you as the coder have a genuine need to do exactly this. How do you get around the limitation? Well, one way is to name Bar’s property differently:

public class Bar:Foo
{
   public string MyBarString {get{return "Bar";}}       
}

Perfectly legal, but it’s not the behavior we want. An instance of Bar will always produce “Foo” for the property MyFooString, when we wanted it to produce “Bar”. Not only do we have to know that our IFoo is specifically a Bar, we also have to know to use the different accessor.

We could also, quite plausibly, forget the parent-child relationship and implement the interface directly:

public class Bar:IFoo
{
   public string MyFooString {get{return "Bar";}}
   public int FooMethod() {...}
}

For this simple example it’s a perfect answer, as long as you only care that Foo and Bar are both IFoos. The usage code a couple examples up would fail to compile because a Bar isn’t a Foo and can’t be assigned as such. However, if Foo had some useful method “FooMethod” that Bar needed, now you can’t inherit that method; you’d either have to clone its code in Bar, or get creative:

public class Bar:IFoo
{
   public string MyFooString {get{return "Bar";}}
   private readonly theFoo = new Foo();

   public int FooMethod(){return theFoo.FooMethod();}
}

This is an obvious hack, and while some implementations of O-O language specs amount to little more than this, conceptually it’s wrong; if consumers of Bar need to expose Foo’s functionality, Bar should be a Foo, not have a Foo.

Obviously, if we controlled Foo, we can make it virtual, then override it. This is the conceptual best practice in our current universe when a member is expected to be overridden, and would hold in any alternate universe that didn’t allow hiding:

public class Foo:IFoo
{
   public virtual string MyFooString {get{return "Foo";}}
   //...
}

public class Bar:Foo
{
   public override string MyFooString {get{return "Bar";}}
}

The problem with this is that virtual member access is, under the hood, relatively more expensive to perform, and so you typically only want to do it when you need to. The lack of hiding, however, forces you to be pessimistic about the members which another coder that doesn’t control your source code might want to reimplement; the “best practice” for any non-sealed class would be to make everything virtual unless you specifically didn’t want it to be. It also still doesn’t give you the exact behavior of hiding; the string will always be “Bar” if the instance is a Bar. Sometimes it is genuinely useful to leverage the layers of hidden state data, based on the level of inheritance at which you’re working.

In summary, allowing member hiding is the lesser of these evils. Not having it would generally lead to worse atrocities committed against object-oriented principles than allowing it does.

4

Your question could be read two ways: either you’re asking about variable/function scope in general, or you’re asking a more specific question about scope in an inheritance hierarchy. You didn’t mention inheritance specifically, but you did mention hard to find bugs, which sounds more like scope in the context of inheritance than plain scope, so I’ll answer both questions.

Scope in general is a good idea, because it allows us to focus our attention on one specific (hopefully small) portion of the program. Because it lets local names always win, if you read only the portion of the program that’s in a given scope, then you know exactly what parts were defined locally and what was defined elsewhere. Either the name refers to something local, in which case the code that defines it is right in front of you, or it’s a reference to something outside the local scope. If there aren’t any non-local references that could change out from under us (especially global variables, which could be changed from anywhere), then we can evaluate whether the part of the program in the local scope is correct or not without referring to any part of the rest of the program at all.

It may possibly occasionally lead to a few bugs, but it more than compensates by preventing an enormous amount of otherwise possible bugs. Other than making a local definition with the same name as a library function (don’t do that), I can’t see an easy way to introduce bugs with local scope, but local scope is what lets many parts of the same program use i as the index counter for a loop without clobbering each other, and lets Fred down the hall write a function that uses a string named str that won’t clobber your string with the same name.

I found an interesting article by Bertrand Meyer that discusses overloading in the context of inheritance. He brings up an interesting distinction, between what he calls syntactic overloading (meaning that there are two different things with the same name) and semantic overloading (meaning that there are two different implementations of the same abstract idea). Semantic overloading would be fine, since you meant to implement it differently in the subclass; syntactic overloading would be the accidental name collision that caused a bug.

The difference between overloading in an inheritance situation which is intended and which is a bug is semantics (the meaning), so the compiler has no way of knowing whether what you did is right or wrong. In a plain scope situation, the right answer is always the local thing, so the compiler can figure out what the right thing is.

Bertrand Meyer’s suggestion would be to use a language like Eiffel, which doesn’t allow name clashes like this and forces the programmer to rename one or both, thus avoiding the problem entirely. My suggestion would be to avoid using inheritance entirely, also avoiding the problem entirely. If you can’t or don’t want to do either of those things, there are still things you can to to reduce the probability of having a problem with inheritance: follow the LSP (Liskov Substitution Principle), prefer composition over inheritance, keep your inheritance hierarchies shallow, and keep the classes in an inheritance hierarchy small. Also, some languages may be able to issue a warning, even if they wouldn’t issue an error, as a language like Eiffel would.

Here are my two cents.

Programs can be structured into blocks (functions, procedures) that are self-contained units of program logic.
Each block can refer to “things” (variables, functions, procedures) using names / identifiers. This mapping from names to things is called binding.

The names used by a block fall into three categories:

  1. Locally defined names, e.g. local variables, that are only known inside the block.
  2. Arguments that are bound to values when the block is invoked and can be used by the caller to specify input / output parameter of the block.
  3. External names / bindings that are defined in the environment in which the block is contained and are in scope within the block.

Consider for example the following C program

#include<stdio.h>

void print_double_int(int n)
{
  int d = n * 2;

  printf("%dn", d);
}

int main(int argc, char *argv[])
{
  print_double_int(4);
}

The function print_double_int has a local name (local variable) d, and argument n, and uses the external, global name printf, which is in scope but not defined locally.

Notice that printf could also be passed as an argument:

#include<stdio.h>

void print_double_int(int n, int printf(const char *, ...))
{
  int d = n * 2;

  printf("%dn", d);
}

int main(int argc, char *argv[])
{
  print_double_int(4, printf);
}

Normally, an argument is used to specify input / output parameters of a function (procedure, block), whereas global names are used to refer to things like library functions that “exist in the environment”, and therefore it is more convenient to mention them only when they are needed.
Using arguments instead of global names is the main idea of dependency injection, which is used when dependencies must be made explicit instead of being resolved by looking at the context.

Another similar use of externally defined names can be found in closures. In this case a name defined in the lexical context of a block can be used within the block, and the value bound to that name will (typically) continue to exist as long the block refers to it.

Take for example this Scala code:

object ClosureExample
{
  def createMultiplier(n: Int) = (m: Int) => m * n

  def main(args: Array[String])
  {
    val multiplier3 = createMultiplier(3)
    val multiplier5 = createMultiplier(5)

    // Prints 6.
    println(multiplier3(2))

    // Prints 10.
    println(multiplier5(2))
  }
}

The return value of the function createMultiplier is the closure (m: Int) => m * n, which contains the argument m and the external name n. The name n is resolved by looking at the context in which the closure is defined: the name is bound to the argument n of function createMultiplier. Notice that this binding is created when the closure is created, i.e. when createMultiplier is invoked. So the name n is bound to the actual value of an argument for a particular invocation of the function. Contrast this with the case of a library function like printf, which is resolved by the linker when the program’s executable is built.

Summarizing, it can be useful to refer to external names inside a local block of code so that you

  • don’t need / want to pass externally defined names explicitly as arguments, and
  • you can freeze bindings at runtime when a block is created, and then access it later when the block is invoked.

Shadowing comes in when you consider that in a block you are only interested in relevant names that are defined in the environment, e.g. in the printf function that you want to use. If by chance you want to use a local name (getc, putc, scanf, …) that has already been used in the environment, you simple want to ignore (shadow) the global name.
So, when thinking locally, you do not want to consider the whole (possibly very big) context.

In the other direction, when thinking globally, you want to ignore the internal details of the local contexts (encapsulation). Therefore you need shadowing, otherwise adding a global name could break every local block that was using that name already.

Bottom line, if you want a block of code to refer to externally defined bindings, you need shadowing to protect local names from global ones.

Honestly, Eric Lippert, the principle developer on the C# compiler team, explains it pretty well (thanks Lescai Ionel for the link). .NET’s IEnumerable and IEnumerable<T> interfaces are good examples of when member hiding is useful.

In the early days of .NET, we didn’t have generics. So the IEnumerable interface looked like this:

public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

This interface is what allowed us to foreach over a collection of objects, however we had to cast all those objects in order to use them properly.

Then came generics. When we got generics, we also got a new interface:

public interface IEnumerable<T> : IEnumerable
{
    IEnumerator<T> GetEnumerator();
}

Now we don’t have to cast objects while we’re iterating through them! Woot! Now, if member hiding was not allowed, the interface would have to look something like this:

public interface IEnumerable<T> : IEnumerable
{
    IEnumerator<T> GetEnumeratorGeneric();
}

This would be kind of silly, because GetEnumerator() and GetEnumeratorGeneric() in both cases do pretty much exactly the same thing, but they have slightly different return values. They are so similar, in fact, that you pretty much always want to default to the generic form of GetEnumerator, unless you’re working with legacy code that was written before generics were introduced into .NET.

Sometimes member hiding does allow more room for nasty code and difficult-to-find bugs. However sometimes it’s useful, such as when you want to change a return type without breaking legacy code. That’s just one of those decisions language designers have to make: Do we inconvenience the developers who legitimately need this feature and leave it out, or do we include this feature into the language and catch flak from those who are victims of its misuse?

1

I can think of only two very good answers and probably most people wont like it, since this is stackoverflow (“the place to copy algorithms/code from”):

It is very easy to 1. copy-paste code or 2. detect changes from copied code blocks, since one can use string search (and simple normalization with a formatter).

Without 1. easy copy-paste, one needs to rename shadowed variables or introduce more temporary variables.
Without 2. easy comparison, one would need to normalize code to module scope or worse: semantic analysis of modules/objects etc.

Far weaker arguments are

  1. Shadowed variables are immediately and accurately connected on search without further guideline. (prefixing like what modules do is de-facto standard)
  2. Shadowed variables are simpler to implement in the compiler, because they require no additional check. (absolute minimal performance impact, because it can be parallelized per-file)
  3. Shadowed variables are faster to write, since the editor can give auto-suggestion for naming/show links. (properly navigating code is essential and having bad names lead to long term unmaintainable code => any linters do check shadowing)
  4. Some languages have global variables on default, so having a local ones were added later on. (shell languages were written for quickly running and combining scripts and were not intended for larger code bases)

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật