Brendan wrote:For example, there's no reason you can't compile an unmanaged language down to some sort of portable byte-code and then compile that byte-code to native when the program is installed and/or running;
Even in a naive sense, that the phrase "managed code" has, we can see that code management (e.g. compilation) should be automatic. So the bytecode compilation when it is installed or running is a management activity and a managed subject is the bytecode.
Brendan wrote:and no reason you can't use (e.g.) something like libraries to hide the differences between platforms.
The reason here is the need for efficiency, that is wrongly assumed by many developers as a way of coding low level things. Low level on a particular platform requires that platform differences are and will always be accessible.
Brendan wrote:you're finding "desirable attributes" (easier bug finding, faster development, more portability, more standard APIs, etc) and pretending they only apply to managed languages when all of them have nothing to do with managed vs. unmanaged whatsoever.
Once a managed code has been compiled into a native representation it becomes unmanaged (or managed by hardware defined means). But the act of management already has been executed and only because it has taken place the code got an ability to be running.
In contrast an unmanaged code is also managed, but only by a developer with the all tedious steps coded manually in some scripts or whatever it takes. So we have an automatic management vs a manual management. Also all those features (debugging, development speed, learning, portability and so on) are heavily influenced by this split of responsibilities. Debugging is easier due to automated run time information management, portability is a result of actions like automatic conversion, development speed is better because of automated memory management an so on. All those areas are automated and managed by a software instead of a developer. So, if you add those features to unmanaged language, then you will get a managed solution, with all the automatic management in place.
Brendan wrote:If I take 80x86 assembly and run it inside a managed environment (e.g. some sort of virtual machine, possibly using JIT, and possibly even on an very different CPU like ARM) then it is "managed"
Wrong. Management can be performed at any stage of the code's life. From initial writing and up to application uninstall. And the difference is in the amount of work that we have to do manually (in unmanaged fashion, when process is ad hoc and very error prone). It's like crafting things manually vs using a fully automated conveyor.
Brendan wrote:If I took (e.g.) C# code and compiled it directly to native code with none of the run-time checks then it would be "unmanaged" and almost all of the things you're incorrectly attributing to "managed" would still apply to "unmanaged C#".
Unless you compile the code under management of a virtual machine, all your activity is unmanaged (i.e. handy craft).
Brendan wrote:I'd be tempted to say that the best use of "managed" is during testing (where the performance doesn't matter and a higher chance of finding bugs sooner is more important) - e.g. use "managed" to find the bugs, then (after the bugs are found/fixed) compile it as unmanaged for the end user's to use without unnecessary overhead.
It's almost as you have painted, but with the final step also automated - a JIT compiles the code into unmanaged form for you. And if you have control over the JIT you can order it to remove runtime checks (if you sure that there are no more bugs), so the efficiency will not be compromised.
Brendan wrote:An even better idea is to run the code in an interpreted testing environment where you can stop it anywhere and investigate all the variable's contents, modifying the code while it's suspended, etc; and where you can run code in "immediate mode"
But don't forget about the next automated step - just let the JIT to do it for you.
Brendan wrote:You can do exactly the same with (e.g.) exception handling in C++ (or exception handling in every language that supports it with, regardless of whether it's managed or not); and it's just another thing you're incorrectly attributing to "managed".
Wrong. Because having an illegal pointer is a legal state for unmanaged program. If you are happy enough and GP has taken place right after the wrong pointer was followed, then it is possible to recover your program, but if a happiness is not with you this day, then corrupted memory will prevent any effort to manage the unmanageable situation.
Brendan wrote:Great. I'll add
garbage collection to the growing list of things you've mistakenly attributed to "managed".
And next you should add many more things until your code becomes really managed by an automated process. Having just one wheel doesn't mean you can drive your car. A car is a complex of things. And every part is important. And you can't just throw away some gear and hope that the car is still managed.
Brendan wrote:After you've found all the bugs and you no longer care about correctness; why would you want additional overhead for no reason forever? You'd only want security/isolation.
Security/isolation after "you've found all the bugs" is a matter of hardware failures. And again we are going to discuss the speed of an application crash. Or it is just a misbehaving user, that pushes brake when he wants his car to run. Both cases are equally bad for managed and unmanaged solutions because they are outside the planned (and bug free) system behavior.