33

Question: Why can't Java/C# implement RAII?

Clarification: I am aware the garbage collector is not deterministic. So with the current language features it is not possible for an object's Dispose() method to be called automatically on scope exit. But could such a deterministic feature be added?

My understanding:

I feel an implementation of RAII must satisfy two requirements:
1. The lifetime of a resource must be bound to a scope.
2. Implicit. The freeing of the resource must happen without an explicit statement by the programmer. Analogous to a garbage collector freeing memory without an explicit statement. The "implicitness" only needs to occur at point of use of the class. The class library creator must of course explicitly implement a destructor or Dispose() method.

Java/C# satisfy point 1. In C# a resource implementing IDisposable can be bound to a "using" scope:

void test()
{
    using(Resource r = new Resource())
    {
        r.foo();
    }//resource released on scope exit
}

This does not satisfy point 2. The programmer must explicitly tie the object to a special "using" scope. Programmers can (and do) forget to explicitly tie the resource to a scope, creating a leak.

In fact the "using" blocks are converted to try-finally-dispose() code by the compiler. It has the same explicit nature of the try-finally-dispose() pattern. Without an implicit release, the hook to a scope is syntactic sugar.

void test()
{
    //Programmer forgot (or was not aware of the need) to explicitly
    //bind Resource to a scope.
    Resource r = new Resource(); 
    r.foo();
}//resource leaked!!!

I think it is worth creating a language feature in Java/C# allowing special objects that are hooked to the stack via a smart-pointer. The feature would allow you to flag a class as scope-bound, so that it always is created with a hook to the stack. There could be options for different types of smart pointers.

class Resource - ScopeBound
{
    /* class details */

    void Dispose()
    {
        //free resource
    }
}

void test()
{
    //class Resource was flagged as ScopeBound so the tie to the stack is implicit.
    Resource r = new Resource(); //r is a smart-pointer
    r.foo();
}//resource released on scope exit.

I think implicitness is "worth it". Just as the implicitness of garbage collection is "worth it". Explicit using blocks are refreshing on the eyes, but offer no semantic advantage over try-finally-dispose().

Is it impractical to implement such a feature into the Java/C# languages? Could it be introduced without breaking old code?

mike30
  • 2,788
  • 2
  • 16
  • 19
  • 3
    It's not impractical, it's **impossible**. The C# standard does not guarantee destructors/`Dispose`s are _ever_ run, regardless of how they're triggered. Adding implicit destruction at end of scope will not help that. – Telastyn Oct 30 '13 at 17:00
  • 23
    @Telastyn Huh? What the C# standard says now is of no relevance, since we're discussing changing that very document. The only issue is whether this is practical to do, and for that the only interesting bit about the current lack of a guarantee is the *reasons* for this lack-of-guarantee. Note that for `using` the execution of `Dispose` *is* guaranteed (well, discounting the process suddenly dying without an exception being thrown, at which point all cleanup presumably becomes moot). –  Oct 30 '13 at 17:08
  • @Telastyn. It's currently impossible. But I'm interested in the ability to add smart pointers to Java seamlessly. It is a language change that will likely never happen, but I want to know the technical reasons smart-pointers cannot be added seamlessly. – mike30 Oct 30 '13 at 17:08
  • 1
    Sort-of duplicate of http://programmers.stackexchange.com/questions/118295/did-the-developers-of-java-consciously-abandon-raii/118444 – dan04 Oct 30 '13 at 18:26
  • 4
    duplicate of [Did the developers of Java consciously abandon RAII?](http://programmers.stackexchange.com/questions/118295), though the accepted answer is **completely** incorrect. The short answer is that Java uses reference *(heap)* semantics rather than value *(stack)* semantics, so deterministic finalization is not very useful/possible. C# *does* have value-semantics (`struct`), but they are typically avoided except in very special cases. [See also](http://blogs.msdn.com/b/oldnewthing/archive/2010/08/10/10048150.aspx). – BlueRaja - Danny Pflughoeft Oct 30 '13 at 18:59
  • 2
    It's similar, not exact duplicate. – Maniero Oct 30 '13 at 19:36
  • 3
    http://blogs.msdn.com/b/oldnewthing/archive/2010/08/10/10048150.aspx is a relevant page to this question. – Maniero Oct 30 '13 at 19:50
  • 1
    FYI, Java has a similar construct since version 7, the syntax is `try(Resource r = new Resource()) { hurr; durr; }`. That's as close as you get and fairly similar to what many modern languages do (e.g., Python's `with` keyword). – TC1 Oct 30 '13 at 20:56
  • 2
    At least for .Net, the designers [made a deliberate decision](http://msdn.microsoft.com/en-us/library/0t81zye4(v=vs.71).aspx) to move away from the COM reference-counting model, so that the garbage collector could cope with circular references and also for performance reasons. "If a group of objects contain references to each other, but none of these object are referenced directly or indirectly from stack or shared variables, then garbage collection will automatically reclaim the memory." – MarkJ Oct 30 '13 at 21:00
  • related: [Disadvantages of scoped-based memory management](http://programmers.stackexchange.com/questions/231789/disadvantages-of-scoped-based-memory-management) – gnat May 22 '14 at 11:07

5 Answers5

26

The biggest difficulty in implementing something like this for Java or C# would be defining how resource transfer works. You would need some way to extend the life of the resource beyond the scope. Consider:

class IWrapAResource
{
    private readonly Resource resource;
    public IWrapAResource()
    {
        // Where Resource is scope bound
        Resource builder = new Resource(args, args, args);

        this.resource = builder;
    } // Uh oh, resource is destroyed
} // Crap, there's no scope for IWrapAResource we can bind to!

What's worse is that this may not be obvious to the implementer of IWrapAResource:

class IWrapSomething<T>
{
    private readonly T resource; // What happens if T is Resource?
    public IWrapSomething(T input)
    {
        this.resource = input;
    }
}

Something like C#'s using statement is probably as close as you're going to come to having RAII semantics without resorting to reference counting resources or forcing value semantics everywhere like C or C++. Because Java and C# have implicit sharing of resources managed by a garbage collector, the minimum a programmer would need to be able to do is choose the scope to which a resource is bound, which is exactly what using already does.

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
Billy ONeal
  • 8,073
  • 6
  • 43
  • 57
  • Assuming you don't have a need to refer to a variable *after it's gone out of scope* (and there really shouldn't be such a need), I claim that you can still make an object self-disposing by writing a finalizer for it. The finalizer is called just before the object is garbage collected. See http://msdn.microsoft.com/en-us/library/0s71x931.aspx – Robert Harvey Oct 30 '13 at 16:51
  • 9
    @Robert: A correctly written program cannot assume finalizers ever run. http://blogs.msdn.com/b/oldnewthing/archive/2010/08/09/10047586.aspx – Billy ONeal Oct 30 '13 at 16:52
  • 1
    Hm. Well, that's probably why they came up with the `using` statement. – Robert Harvey Oct 30 '13 at 16:54
  • @RobertHarvey That and the fact that even if the finalizer runs, it may run after a very long delay (during which you may run out of whatever scarce resource you insisted on leaving to the GC). –  Oct 30 '13 at 16:57
  • The `IWrapSomething` problem already exists in C#. If `T` is `IDisposable`, then it won't be disposed. – svick Oct 30 '13 at 17:17
  • @svick: Yes, but in C#, someone who instantiates `IWrapSomething` for a `T` which is disposable needs to understand the ownership and act accordingly. If `T` is bound to a scope, the caller has no way of saying "please don't destroy this, I need it to live longer". – Billy ONeal Oct 30 '13 at 17:28
  • 2
    Exactly. This is a huge source of newbie bugs in C++, and would be in Java/C# as well. Java/C# don't eliminate the ability to leak the reference to a resource that's about to be destroyed, but by making it both explicit and optional they remind the programmer and give him a conscious choice of what to do. – Aleksandr Dubinsky Oct 30 '13 at 19:34
  • 1
    @svick It's not up to `IWrapSomething` to dispose of `T`. Whoever created `T` needs to worry about that, whether using `using`, being `IDisposable` itself, or having some ad-hoc resource lifecycle scheme. – Aleksandr Dubinsky Oct 30 '13 at 19:42
  • 1
    @AleksandrDubinsky: Java and C# don't eliminate leaks. Careful design is still necessary to ensure you aren't referencing the whole world in terms of memory. They don't attempt to address non-memory resources at all, and failing to release a resource like this is a common source of bugs in Java and C# programs, because people don't pay as much attention to ownership as they should. – Billy ONeal Nov 01 '13 at 18:30
  • C++/CLI implements some good RAII-ish concepts which other languages could support just as well. Being able to tag fields as "owning" the resources identified thereby, having a compiler auto-generate a `Dispose` which takes care of fields thus tagged, and further having the compiler take care of such disposal when a constructor throws, could (and IMHO should) have been standard language features--much more generally relevant than "destructors". – supercat Feb 16 '14 at 00:36
19

Such a language extension would be significantly more complicated and invasive than you seem to think. You can't just add

if the life-time of a variable of a stack-bound type ends, call Dispose on the object it refers to

to the relevant section of the language spec and be done. I'll ignore the problem of temporary values (new Resource().doSomething()) which can be solved by slightly more general wording, this is not the most serious issue. For example, this code would be broken (and this sort of thing probably becomes impossible to do in general):

File openSavegame(string id) {
    string path = ... id ...;
    File f = new File(path);
    // do something, perhaps logging
    return f;
} // f goes out of scope, caller receives a closed file

Now you need user-defined copy constructors (or move constructors) and start invoking them everywhere. Not only does this carry performance implications, it also makes these things effectively value types, whereas almost all other objects are reference types. In Java's case, this is a radical deviation from how objects work. In C# less so (already has structs, but no user-defined copy constructors for them AFAIK), but it still makes these RAII objects more special. Alternatively, a limited version of linear types (cf. Rust) may also solve the problem, at the cost of prohibiting aliasing including parameter passing (unless you want to introduce even more complexity by adopting Rust-like borrowed references and a borrow checker).

It can be done technically, but you end up with a category of things which are very different from everything else in the language. This is almost always a bad idea, with consequences for implementers (more edge cases, more time/cost in every department) and users (more concepts to learn, more possibility of bugs). It's not worth the added convenience.

  • Why you need copy/move constructor? File stills a reference type. In that situation f which is a pointer is copied to the caller and it is responsible to dispose the resource (the compiler implicitly would put a try-finally-dispose pattern in the caller instead) – Maniero Oct 30 '13 at 19:34
  • 2
    @bigown If you treat every reference to a `File` this way, nothing changes and `Dispose` is never called. If you always call `Dispose`, you can't do anything with disposable objects. Or are you proposing some scheme for sometimes disposing and sometimes not? If so, please describe it in detail and I'll tell you situations in which it fails. –  Oct 30 '13 at 20:05
  • I fail to see what you said now (i'm not saying you are wrong). The object has a resource, not the reference. – Maniero Oct 30 '13 at 20:30
  • My understanding, changing you example to just a return, is that the compiler would insert a try just before the resource acquisition (line 3 at your example) and the finally-dispose block just before the end of scope (line 6). No problem here, agree? Back to your example. The compiler see a transfer, it couldn't insert try-finally here but the caller will receive a (pointer to) File object and assuming the caller is not transferring this object again, compiler will insert try-finally pattern there. In other words every IDisposable object not transferred need to apply try-finally pattern. – Maniero Oct 30 '13 at 20:31
  • 2
    @bigown In other words, don't call `Dispose` if a reference escapes? Escape analysis is an old and hard problem, this won't always work without further changes to the language. When a reference is passed to another (virtual) method (`something.EatFile(f);`), should `f.Dispose` be called at the end of the scope? If yes, you break callers that store `f` for later use. If not, you leak the resource if the caller does *not* store `f`. The only somewhat simple way to remove this is a linear type system, which (as I already discussed later in my answer) instead introduces many other complications. –  Oct 30 '13 at 20:37
  • Yes, exactly what I said. I understand you now. There are problems for *other* situations, sure. Probably the compiler would need to forbid some constructs. Compilers do this every time. If this is good or bad is matter of discussion which doesn't fit here. I'm not sure if this new example is unsolvable (I have no enough information to discuss this). So you could say write _using_ is easier and I can agree, but the point of this question it is if is is feasible. If you ask me if I want get rid of _using_ on C#, I say a big NO. I'm talking by language design pov. – Maniero Oct 30 '13 at 20:56
  • @bigown Of course you can adopt a linear type system without any extra convenience features (such as borrowed references). That's one of the options I describe in my answer! (The other being value semantics and copy/move constructors, which you apparently read as the *only* solution I propose.) My point is that OP's proposal is insufficient in isolation, and that any way of solving these shortcomings results in a drastically different (sub)language and a lot of extra concepts and work for everyone. –  Oct 30 '13 at 21:04
  • I totally understand now. – Maniero Oct 30 '13 at 22:08
  • @delnan: While perfect escape analysis is equivalent to the Halting Problem, I would think it useful for parameters, fields, and return values to have declarative traits which would confine their behaviors to deal with the common situation where all references to a mutable object are, and must remain, under the control of a single entity. To allow use of pre-existing collection types, it would be necessary to have a means of patch-attaching attributes to their methods without having to recompile the collection (e.g. to say that objects passed to `someCollection.Add()` will never... – supercat Apr 10 '14 at 17:08
  • ...be exposed by `MyCollection` to anything that doesn't hold a reference to the instance `someCollection` to which they were added). If the traits could be applied to generic types, they could really do a lot to prevent mutability-related bugs. – supercat Apr 10 '14 at 17:10
  • @supercat I don't think comments on a half year old answer are an appropriate venue for tangentially related language design ideas, in particular if they don't address the very same problems outlined in the answer. Also, if you want to further thought into that direction, you should really look into linear type systems, Rust in particular. –  Apr 10 '14 at 22:24
14

The reason why RAII can't work in a language like C#, but it works in C++, is because in C++ you can decide whether an object is truly temporary (by allocating it on the stack) or whether it is long-lived (by allocating it on the heap using new and using pointers).

So, in C++, you can do something like this:

void f()
{
    Foo f1;
    Foo* f2 = new Foo();
    Foo::someStaticField = f2;

    // f1 is destroyed here, the object pointed to by f2 isn't
}

In C#, you can't differentiate between the two cases, so the compiler would have no idea whether to finalize the object or not.

What you could do is to introduce some kind of special local variable kind, that you can't put into fields etc.* and that would be automatically disposed when it goes out of scope. Which is exactly what C++/CLI does. In C++/CLI, you write code like this:

void f()
{
    Foo f1;
    Foo^ f2 = gcnew Foo();
    Foo::someStaticField = f2;

    // f1 is disposed here, the object pointed to by f2 isn't
}

This compiles to basically the same IL as the following C#:

void f()
{
    using (Foo f1 = new Foo())
    {
        Foo f2 = new Foo();
        Foo.someStaticField = f2;
    }
    // f1 is disposed here, the object pointed to by f2 isn't
}

To conclude, if I were to guess why the designers of C# didn't add RAII, it's because they thought that having two different types of local variables is not worth it, mostly because in a language with GC, deterministic finalization is not useful that often.

* Not without the equivalent of the & operator, which in C++/CLI is %. Though doing so is “unsafe” in the sense that after the method ends, the field will reference a disposed object.

svick
  • 9,999
  • 1
  • 37
  • 51
7

If what bothers you with using blocks is their explicitness, perhaps we can take a small baby-step towards less explicitness, rather than changing the C# spec itself. Consider this code:

public void ReadFile ()
{
  string filename = "myFile.dat";
  local Stream file = File.Open(filename);
  file.Read(blah blah blah);
}

See the local keyword I added? All it does is add a bit more syntactic sugar, just like using, telling the compiler to call Dispose in a finally block at the end of the variable's scope. That is all. It's totally equivalent to:

public void ReadFile ()
{
  string filename = "myFile.dat";
  using (Stream file = File.Open(filename))
  {
      file.Read(blah blah blah);
  }
}

but with an implicit scope, rather than an explicit one. It's simpler than the other suggestions since I don't have to have the class defined as scope-bound. Just cleaner, more implicit syntactic sugar.

There might be issues here with hard-to-resolve scopes, though I can't see it right now, and I'd appreciate anyone who can find it.

Update: Since the initial writing of this, C# has gotten this feature with C#8. Only instead of local as suggested here the keyword is simply using, as it replaces a using-block.

Metallkiller
  • 103
  • 3
Avner Shahar-Kashtan
  • 9,166
  • 3
  • 29
  • 37
  • I think `using` would be a better choice than `local`, as it's less confusing ("local variable" already means something different which is completely independent from the proposed extension, and `using` invokes associations with the thing it desugars to). I think there aren't any other issues (it doesn't dispose *as* promptly but that's the point and inherent to the style of RAII discussed here). –  Oct 30 '13 at 19:26
  • +1. That is some sweet syntax! In some ways even a smart pointer is explicit if you consider the act of declaring the pointer as "smart" to be an "explicit" action. My thought is to move the smartness to the type of the class so it is enforced by the type system. This would catch any non-smart use of the object at compile time and could be considered more "implicit". – mike30 Oct 30 '13 at 19:27
  • 1
    @mike30 but moving it to the type definition leads you exactly to the problems others listed - what happens if you pass the pointer to a different method or return it from the function? This way the scoping is declared in the scope, not elsewhere. A type might be Disposable, but it's not up to it to call Dispose. – Avner Shahar-Kashtan Oct 30 '13 at 19:30
  • 3
    @mike30: Meh. All this syntax does is remove the braces and, by extension, the scoping control they provide. – Robert Harvey Oct 30 '13 at 19:31
  • 1
    @RobertHarvey Exactly. It sacrifices some flexibity for cleaner, less nested code. If we take @delnan's suggestion and reuse the `using` keyword, we can keep the existing behavior and use this as well, for the cases where we don't need the specific scope. Have brace-less `using` default to the current scope. – Avner Shahar-Kashtan Oct 30 '13 at 19:33
  • @Robert *shrug*. I'm not going to open a feature request on Connect for it. I agree that the problem presented by the OP isn't that big. But if I were to try and address it, I'd probably go this route. Programmers.SE doesn't require my solutions to be entirely feasible, do they? :) – Avner Shahar-Kashtan Oct 30 '13 at 19:37
  • 1
    I've got no problem with semi-practical exercises in language design. – Avner Shahar-Kashtan Oct 30 '13 at 19:39
  • 1
    @RobertHarvey. You seem to have a bias against anything not currently implemented in C#. We wouldn't have generics, linq, using-blocks, ipmlicit types, etc if we were satisfied with C# 1.0. This syntax does not solve the issue of implicitness, but it is a good sugar to bind to the current scope. – mike30 Oct 30 '13 at 19:39
  • I certainly don't favor major machinery changes for what apparently amounts to a mundane syntax style variation. If that makes be seem inflexible, then so be it. – Robert Harvey Oct 30 '13 at 19:41
  • Do you prefer using-blocks over try-finally-dispose()? It too amounts to nothing but a mundane syntax variation. – mike30 Oct 30 '13 at 19:43
  • I fail to see implicitness which is the original requirement from OP. "more implicit than" is strange to me, or it is implicit or it is explicit. Disclaimer: I am just interested in language design here, I'm not saying that C# or Java should implement this. – Maniero Oct 30 '13 at 19:47
  • @mike20: `using` blocks are more than just sugar. You might as well call `async` sugar; it's not. Both constructs have special compiler support. Both constructs seek to provide meaning beyond what amounts to a simple syntax variation. – Robert Harvey Oct 30 '13 at 19:51
  • @bigown. I went off on a tangent unrelated to the proposed sugar. If the requirement of scope binding is moved to the type it can be enforced by the type system. This way it cannot be used is a regular heap reference. So there is no requirement for the programmer to "remember" to declare a pointer as smart (like there is in C++). If you cannot possible use the object without the pointer being smart, then it is implicit. – mike30 Oct 30 '13 at 19:52
  • @RobertHarvey. I am not proposing replacing using-blocks. I propose to add smart pointers in a "seamless" way. I never suggested removing anything. I am suggesting adding a feature, that feature being implicitness in binding to a scope. – mike30 Oct 30 '13 at 19:55
  • 1
    @RobertHarvey. No the using-block is not anything more than sugar. It is *exactly* equivalent to try-finally-dispose. That's not a bad thing, I love sugar. But it is just that. – mike30 Oct 30 '13 at 19:57
  • 1
    @mike30: Sorry, but you're wrong. `using` requires compiler support, because it has to recognize that the type it is `using` implements the `IDisposable` interface. It is not simply a language macro. – Robert Harvey Oct 30 '13 at 20:00
  • @mike20 but if you need to be aware that a type is a resource and you are forced to write something to tell to compiler to do a proper work you're explicit. I disagree with Robert in almost everything he says in this question but he is right saying this answer just get rid of braces and a nested scope and when he's saying the _using_ is not a sugar. – Maniero Oct 30 '13 at 20:10
  • @bigown: Thanks for the vote of confidence. I deleted my answer anyway, which apparently wasn't helping anyone. I wasn't aware, when I answered the question, that this was merely a hypothetical exercise. I did learn a few things, however. – Robert Harvey Oct 30 '13 at 20:24
  • @RobertHarvey IMHO your answer is not wrong either, just it was not fit in this question. For me it's about language design. I agree with you that C# or even Java team shouldn't waste resources in that feature. I see the usefulness of this feature and I see the cost for the language and for the implementation. – Maniero Oct 30 '13 at 20:39
  • @RobertHarvey. The definition of sugar is ambiguous, but using-blocks are nothing more than a syntax expansion to try-finally-dispose. The fact it requires a compiler change does not make it non-sugar. Unless your programming in lisp, your sugar will likely require a compiler change. – mike30 Oct 30 '13 at 21:32
  • I like this idea, though I'm not super-fond of the word "local". It's personal of course, but I'd suggest the word "scoped" instead. To me this gives a hint that something may happen that's related to the scope - and indeed, we're calling Dispose at the end of the scope. – redtuna Oct 31 '13 at 03:57
  • @AvnerShahar-Kashtan can you tell me where did you find it? I can't find `local` keyword description in the C# docs. – Konrad Jul 03 '19 at 08:00
  • 1
    @Konrad that's because it doesn't exist - I proposed it as an alternative solution to the OP's suggestions. However, in the years since I made it, C# *did* add this ability with C# 8's [using declarations](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#using-declarations) – Avner Shahar-Kashtan Jul 03 '19 at 08:02
  • @AvnerShahar-Kashtan makes sense. – Konrad Jul 03 '19 at 08:06
1

For an example of how RAII does work in a garbage-collected language, check the with keyword in Python. Instead of relying on deterministically-destroyed objects, it let's you associate __enter__() and __exit__() methods to a given lexical scope. A common example is:

with open('output.txt', 'w') as f:
    f.write('Hi there!')

As with C++'s RAII style, the file would be closed when exiting that block, no matter if it's a 'normal' exit, a break, an immediate return or an exception.

Note that the open() call is the usual file opening function. to make this work, the returned file object includes two methods:

def __enter__(self):
  return self
def __exit__(self):
  self.close()

This is a common idiom in Python: objects that are associated with a resource typically include these two methods.

Note that the file object could still remain allocated after the __exit__() call, the important thing is that it is closed.

Javier
  • 9,888
  • 1
  • 26
  • 35
  • 9
    `with` in Python is almost exactly like `using` in C#, and as such not RAII as far as this question is concerned. –  Oct 30 '13 at 18:06
  • 1
    Python's "with" is scope-bound resource management but it is missing the implicitness of a smart-pointer. The act of declaring a pointer as smart could be considered "explicit", but if the compiler enforced smartness as part of the objects type, it would lean towards "implicit". – mike30 Oct 30 '13 at 18:22
  • AFAICT, the point of RAII is establishing strict scoping to resources. if you're only interested in being done by deallocating objects, then no, garbage-collected languages can't do it. if you're interested in consistently releasing resources, then this is a way to do it (another is `defer` in Go language). – Javier Oct 30 '13 at 19:07
  • about implicitness vs explicitness, i think you're right that C++, Java and C# favor 'implicit' constructions, but the converse is true in some other languages. the [zen of python](http://www.python.org/dev/peps/pep-0020/) explicitly states "Explicit is better than implicit." right in the second line (after "Beautiful is better than ugly.") of course, beauty is in the eye of the beholder... – Javier Oct 30 '13 at 19:09
  • 1
    Actually, I think it's fair to say that Java and C# strongly favor explicit constructions. Otherwise, why bother with all the ceremony inherent in using Interfaces and inheritance? – Robert Harvey Oct 30 '13 at 19:36
  • @RobertHarvey Wrong interpretation of explicit. Some things can't be made implicit, this Zen entry is for when both are possible (e.g. qualifying object members instead of an implicit `this`/`self`). Depending on what you mean by "ceremony inherent in using interfaces", it's either necessary to get *static* type checking or to avoid hainv a structural type system with all its downsides. Similar for inheritance, the compiler can't guess which class (if any) your classes should inherit from, can it? –  Oct 30 '13 at 20:10
  • @delnan: Not sure what point you're trying to make. You're still describing what could be considered "explicit." Whether it can be made implicit or not doesn't make it any less explicit. – Robert Harvey Oct 30 '13 at 20:22
  • @RobertHarvey Perhaps I misunderstood you. How would you make interfaces or inheritance "implicit"? –  Oct 30 '13 at 20:26
  • @delnan: You wouldn't. Therefore you wouldn't favor such a language design if your goal was to be implicit. – Robert Harvey Oct 30 '13 at 20:27
  • 1
    @delnan, Go does have 'implicit' interfaces. – Javier Oct 30 '13 at 21:37
  • @Javier Yes, I know. Its type system is structural, and from what I've heard (yet to do a serious project in Go) it ends up behaving quite differently from nominal interfaces. –  Oct 31 '13 at 12:56