32

In the article: Why POCO, there is this sentence:

Maciej Sobczak puts it well: “I just don’t like when somebody gives me half of the language and tells me that it’s for my own protection”.

I don't understand what he means, even though C# is owned by Microsoft & Java is owned by Oracle, it doesn't mean they hold half of the language, does it? I didn't find any evidence to prove that sentence, and I'm really curious about this. And even more curious about the 'for my own protection' part.

closed as primarily opinion-based by gnat, Daenyth, Thomas Owens Nov 10 '17 at 13:01

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 12
    I interpreted that as critique against letting the programmer do things like freely allocate and free memory and that sort of "protection", but I'm not sure if that was the point he was trying to make. – Kayaman Nov 9 '17 at 14:07
  • 15
    I'm not sure exactly, because the article he's quoting from seems to be dead, but it seems like he's saying that Java and C# are missing a number of C++'s more 'dangerous' or controversial features, like multiple inheritance or template metaprogramming. – GoatInTheMachine Nov 9 '17 at 14:07
  • 3
    The context of the quote is missing (the link is 404), so the only thing you will get here is people guessing at what he probably meant, or (more likely) people just presenting their own opinion. If you actually want to know the context, i.e. what is on the lost page, the best bet is probably to write the author directly, or maybe try to find the lost page through the wayback machine or similar. – JacquesB Nov 9 '17 at 14:45
  • 2
    The statement is missing the point in that, even if you can handle it, you don't always want to expose every possible aspect of software development in a language. Sure you may not have a problem reading memory management code, but other developers may not be incredibly excited to maintain that code. Its similar to the concept of encapsulation. Also C# does let you access quite a bit of stuff through, compiler directives, special attributes, and reflection, not that one should use those things, though. – Mark Rogers Nov 9 '17 at 17:19
  • 32
    For your own good, pay no attention to the people who think that a language must have all the features of C++ to be considered "real" and "complete". Pay no attention to the people who think that type safety, memory safety and well defined behavior are "training wheels". Correctness is becoming the most important aspect of software in most industries and the people who take pride in not caring about it will soon become irrelevant. – Theodoros Chatzigiannakis Nov 9 '17 at 18:35
163

Sobczak isn't talking about corporate ownership. The "half" language that he is missing is all those things that you can't do in many modern languages, even though as a well-educated computer expert he knows they could be made possible: inherit from as many classes as you like. Assign any object to any other without type constraints. Control allocation and freeing resources manually instead of trusting the compiler and run-time to do it for him.

The thing is, all those restrictions were put into programming languages for a reason. We did have languages that allowed all this. Over time we found that the average programmer is better off with a certain amount of restrictions and hand-holding, because the potential of making really bad errors is just too great to be worth the additional power and expressivity.

(Obviously, this sometimes annoys programmers who wouldn't really need that much hand-holding. Their complaints are sometimes legitimate. But people are notoriously bad at assessing their own skills, and many who think they don't need the safeguards do, in fact, very much need them. It isn't always easy to tell apart actual superior intellects who feel held back by restrictions in high-level languages from average coders who just think that complaining will make them look superior, or who don't know any better.)

  • 67
    This is my goto answer. – Neil Nov 9 '17 at 14:10
  • 71
    Also I would add that there is no such thing as superior intellects who don't need the restrictions. It's always safe to assume that everybody messes up sooner or later. And usually the superior the intellect, the bigger the blunder. – Neil Nov 9 '17 at 14:16
  • 29
    There's a bit more to Java and C# than simply preventing people from shooting themselves in the foot. Managing memory took a significant amount of developer time and effort before garbage collection came along, for example, and it's hard to do manual memory management correctly. Garbage collection improves programmer productivity. – Robert Harvey Nov 9 '17 at 16:52
  • 12
    @RobertHarvey I 100% agree. Being a long time C++ programmer, I was skeptical of automatic memory management when moving to C#. Once I got past that, it was incredibly liberating to just not have to worry about it 99% of the time. It freed up my brainpower to think about other issues instead. – 17 of 26 Nov 9 '17 at 16:55
  • 8
    "Assign any object to any other without type constraints."... So, dynamic? – Arturo Torres Sánchez Nov 9 '17 at 17:32
34

This is explained quite nicely in the original source of the quote:

I decided to learn more about C++ and became its faithful passionate - this includes my interest in the way this language is likely to evolve. Moreover, I've noticed that the most high-end and state-of-the-art techniques are needed to develop useful libraries, not the actual applications. Having this in mind, I've tried to write a couple of my own libraries for different purposes (see my download page) and I also try to look over the shoulders of the C++ Boost developers (see my links page) to learn what those high-end techniques are. Spending time on development of libraries that are supposed to be generic and useful at the same time is really demanding. That's why programmers never stop learning.

[…]

I keep playing with C++ and the techniques for writing robust software. To gain wider perspective in the area of reliable software I decided to invest some time in learning Ada (and related stuff), which is a language that seems to be completely abandoned by business even though it was Ada that was really designed for complex and reliable systems. I have to admit that learning Ada was really beneficial for me in the sense that it enabled me to take a more fresh look at my work and development approaches. Most importantly, some of the ideas from the Ada world can be more or less directly applied to C++ with good results in the area of robustness and correctness.

[…]

OK, I forgot. I swore one day not to learn Java. But I did. Well, to the extent that allows me to read and write working code. I have read 'Thinking in Java' (available on-line, free) and 'Core Java' (not online, not free), I was also indirectly involed in some Java development, and... Well, I don't buy it. I just don't like when somebody gives me half of the language and tells me that it's for my own protection. It's like a paper hammer, made light so that nobody will hurt himself when hitting the finger... The same applies to C#. I choose the steel sledge-hammer, so that I can be sure that when I want to play macho, it will withstand.
The question is - why do so many people use it (Java, C#, etc.)? Hmmm... Maybe because it's very good in some places. But there are situations, where both the language and the library show that they were designed rather for applets (initially) than to become do-everything utilities. It just promises too much and gives too little as for catch-all technology. Or as a solution that could plough over any competition..

I like C++ when maximum power and widest perspective is needed. In places where the expressiveness of C++ is not a must-have, languages like Tcl or Python seem to fit the bill. Not only they are open with regard to their evolution, but one can extend and embed them, depending on particular needs. I see a lot of possibilities dreaming in those technologies. I also tend to abandon C as a language for regular programming - this seems to be a reasonable choice only as a target for code generation, otherwise it's too error prone. Today, Ada comes as my likely second choice for more serious projects, provided that I have free choice (which is, unfortunately, not the case most of the time).

So, in other words, the author of that quote likes C++, and he doesn't like Java, and he feels that Java is missing half of C++. And that's all there is to that quote.

  • 18
    Ironically, he dislikes C the exact same reason he like C++, it is very open, allowing a lot of power and a lot of errors. – GreySage Nov 9 '17 at 16:21
  • 8
    He considers C++ to be more expressive than Python – benxyzzy Nov 9 '17 at 17:04
  • 12
    @GreySage That caught my eye too... C is too error prone but C# doesn't give you enough power? C is that far removed from C++? C# doesn't have "unsafe" corners that give you more control? Interesting mix of opinions thats for sure... – WernerCD Nov 9 '17 at 17:12
  • 10
    @WernerCD can't really tell about unsafe C#, but C and C++ have pretty much nothing in common, except that you can beat a basic C90 snippet into a valid C++-ish snippet on which the compiler won't choke. – Quentin Nov 9 '17 at 19:23
23

The article linked to in the blog you posted has been removed, so it's hard to be sure, but as Kilian says, it's likely that when he says "half the language" he means that C# and Java feel like C++ but with a lot of features and constructs removed to make them easier to use or safer.

Back in 2006, when this was written, when C# was relatively young and Java was in many ways immature, and when power vs safety seemed like a trade-off where you could only pick one, this wasn't a totally unreasonable position to take.

These days that position isn't reasonable at all. Just thinking about mainstream languages, C# and Java have matured enormously, borrowing features from other languages (particularly functional) to promote writing safe code. We also have languages like Rust and Swift that are built from the ground up to do this.

If someone looks down on a language because it holds your hand, or says that a language being hard to use is somehow a good thing, I'd take anything they said with a grain of salt. You only have to look at the embarrassing number of bugs found in code we depend on every day, written by the brightest minds in the industry, that would have been trivially avoided by using 'safe' languages, to see why.

  • 6
    I agree with your position in the last paragraph. C++ should be called the "Fountain of Exploits". – Caleb Mauer Nov 9 '17 at 16:57
  • 3
    Also to complement your 2nd paragraph, both Java and C# heavily cribbed C and C++ syntax for various reasons, including enticing existing C/C++ developers with the promise of a lower learning curve. As they've matured, they've added their own features and have their own flavor, but in their early days, it was easier to view them as "C++ but less powerful" since they were more directly positioned as an alternative to C++. – Harrison Paine Nov 9 '17 at 19:44
12

Looking back at the archives, it appears that this quote was from 2003 (despite the article citing it being from 2006). At that time, C# was in Version 1.x, and it was lacking a lot of its modern features:

New features

C# 2.0

  • Generics
  • Partial types
  • Anonymous methods
  • Iterators
  • Nullable types
  • Getter/setter separate accessibility
  • Method group conversions (delegates)
  • Co- and Contra-variance for delegates
  • Static classes
  • Delegate inference

C# 3.0

  • Implicitly typed local variables
  • Object and collection initializers
  • Auto-Implemented properties
  • Anonymous types
  • Extension methods
  • Query expressions
  • Lambda expression
  • Expression trees
  • Partial methods

C# 4.0

  • Dynamic binding
  • Named and optional arguments
  • Generic co- and contravariance
  • Embedded interop types ("NoPIA")

C# 5.0

  • Asynchronous methods
  • Caller info attributes

C# 6.0

  • Compiler-as-a-service (Roslyn)
  • Import of static type members into namespace
  • Exception filters
  • Await in catch/finally blocks
  • Auto property initializers
  • Default values for getter-only properties
  • Expression-bodied members
  • Null propagator (null-conditional operator, succinct null checking)
  • String interpolation
  • nameof operator
  • Dictionary initializer

C# 7.0

  • Out variables
  • Pattern matching
  • Tuples
  • Deconstruction
  • Local functions
  • Digit separators
  • Binary literals
  • Ref returns and locals
  • Generalized async return types
  • Expression bodied constructors and finalizers
  • Expression bodied getters and setters

C# 7.1

  • Async main
  • Default literal expressions
  • Inferred tuple element names

-"C Sharp", Wikipedia (references and links removed)

It's probably more understandable that C# seemed like half-a-language in that context, as it was lacking a lot of what C# is today. It's weird to think that it didn't even have static classes!

More stuff was missing, too, since C#'s been tied to .NET. For example, WPF wasn't around back then; it was all WinForms.

  • static classes may be a poor choice of a missing feature seeing as Java still doesn't have them (the C# kind). Unless this is a jab at Java? – immibis Nov 10 '17 at 0:05
  • 1
    @immibis Not an intentional stab at Java, but, jeeze, really? static classes seem like such a primitive feature; I kinda imagined that they pre-dated instanced classes. – Nat Nov 10 '17 at 0:20
  • 2
    Seems like saying that piston-engine jets predated jet-engine jets; a "non-instanced class" is generally called a module or namespace , except in languages where all code has to be inside a class. (Or calling a bicycle a manual automobile, or calling a landline phone a stationary cellphone, or ...) – immibis Nov 10 '17 at 0:22
  • @Nat - Having static classes is nice, but not having them changes absolutely nothing. You can just make all members of the class static, and all that you lose is a few kinds of compiler errors if you forget that the class was intended to remain static. – Jirka Hanika Nov 10 '17 at 12:24
  • @JirkaHanika Yeah, I'm not a huge fan of static classes in most cases anyway. Honestly I picked it as a feature to call out because it seemed really simple, primitive part of C#; I didn't consider that they weren't in Java. – Nat Jan 4 '18 at 11:42
3

He was complaining of the lack of language features which enable fine-grained control. These include tools for

  • Enforcing immutability (such as the C++ const keyword)
  • Controlling object lifetime and ownership
  • Controlling memory usage, copying and allocation style

This reminds me of one of my criticisms of Java:

everything's a pointer, but pointers don't exist.

In C++ objects, pointers and references are three distinct concepts with clear semantics. In Java you just have the pseudo-object-pointer. By conflating these and eschewing true pointer semantics the object model is less clear.

In a well defined C++ program the programmer can expect references to be valid and non-null. Because of its simplified model, Java cannot make the same guarantees.

Symptoms of this less clear model include the null object pattern and yoda conditionals such as 5.equals(potentiallyNullIntegerReference).

  • 5
    This is very confused. Pointers (in the logical sense exist in Java) you just can't screw around with them. The whole point of simplifying the model is to allow for more guarantees. The logic that you can assume more about code in a language will less restrictions is backwards. More restrictions -> more guarantees. – JimmyJames Nov 9 '17 at 18:02
  • 1
    @JimmyJames the phrase means that, even though all java classes have implicit (yuck, btw) reference semantics, you can't have an actual pointer. For example, there's no way to get a "reference" to a reference. This cripples the language in several places, sometime requiring insane workarounds (see Map.merge when you simply want to update a value in a map). – Quentin Nov 9 '17 at 19:29
  • 3
    @JimmyJames: Some kinds of useful guarantees cannot be practically offered without imposing certain restrictions. Further, some useful optimizations may require imposing some restrictions. Some languages, however, impose pointless restrictions which don't offer any useful guarantees to programmers and shouldn't be required to perform useful optimizations. Some restrictions are simply bad. – supercat Nov 9 '17 at 21:35
  • 3
    @JimmyJames: On the other hand, some of the more fundamental restrictions of Java and "safe-mode" C# let them offer a very useful guarantee that C++ can't: any reference (what in C++ would be a pointer) that is ever observed to identify a particular object will never be observed to identify anything else. – supercat Nov 9 '17 at 21:39
  • 3
    Can you provide some quotes to support your answer? For example, AFAIK, the page doesn't mention const. It does mention "functional programming", however, the language he uses as example is Scheme, which is not a pure functional language (in fact, the designers of Scheme are careful to avoid the use of the word "function" and talk about "procedures"), so it seems he is using the "first-class subroutines" interpretation of FP and not the "referential transparency" one. – Jörg W Mittag Nov 10 '17 at 0:11
1

I agree with @Kilian answer but I will add some elements.

1- Running against a Virtual Machine not the OS

Since Java and C# are running through a Virtual Machine, it is logically expected that you cannot do exactly what you want like when being straight on the OS, because you're likely to corrupt something in the VM. Furthermore with Java being oriented as being platform agnostic, it is even more logic.

2- Tons of applications don't require you to need those kind of stuff.

There are tons of applications that really don't need you to dig through that much of details, yet if you do that with a language that require you to do it you get :

  • More risks to have bugs due to those unnecessary things.
  • More development cost, managing memory and testing it take time and so money!

3- Language are made on some choice weighting cost/usage/risks, like... everything.

With C++ you can do pretty much what you want, that is the choice of C++ people. However the more there is, the more you need to handle.

So things like multiple inheritance are not given up just on the fact that they're dangerous, they're given up because implementing them have a cost (development, maintenancy), all for that for a feature that is rarely get used properly and can generally be rewritten differently.

  • The real cost of multiple inheritance lies in the fact it's not possible to uphold both of the following guarantees: (1) If a member of base-class B is overridden in middle class M, then B's version of that member will only be accessible through M's override; (2) given any reference of type T, converting it to any super-type and back to T will yield a reference equivalent to the original. Both of those guarantees are useful, and supporting multiple inheritance would require giving up at least one. – supercat Nov 10 '17 at 18:25
-1

Simply put all the restrictions in high level languages like C# and Java exist to protect the programmer. They exist not so much to protect the programmer from him/herself, but rather to protect the programmer from other programmers!

How many times do we as programmers encounter libraries that were downright aweful in their coding practices and design but that we were forced to use for one reason or another?

These programs typically have the hallmarks of the old procedural method of programming, with lack of encapsulation, plenty of direct memory writes with little to no error catching or handling. Segfaults pursue en-mass when attempting to use them in any large-scale project.

That's where languages like Java and C# are extremely helpful; it is not that they we enjoy the fact that they don't let us do all the neat things other languages do, It is that we enjoy the lack of headaches we have to endure because other programmers would abuse the neat things that other languages can do.

Interfaces are well worth any sort of trade-off in terms of memory or execution speed in my mind. I hope you can see that in any sort of time-limited mission critical application, all those protections, proper error-handling and generally being certain that memory isn't being qucked with are good things!

  • this doesn't seem to offer anything substantial over points made and explained in prior 5 answers – gnat Nov 9 '17 at 20:45
  • 1
    They exist not so much to protect the programmer from him/herself, but rather to protect the programmer from other programmers! or is it to protect other programmers from the programmer? – Tobia Tesan Nov 9 '17 at 21:09
  • @TobiaTesan That too :) – Akumaburn Nov 9 '17 at 21:12

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