I am going to make an unsubstantiated claim: the person you have been engaging in discourse with is not necessarily overly knowledgeable about what they are speaking of. Any and all readers may accept or object to my claim, and that is fine; I am quite aware that I have no intention of demonstrating it with any depth.
I frankly cannot decide what precisely "free thinking" is supposed to mean in this case, but we can certainly look at discipline, and perhaps fuzzily consider the matter of "hacker language," albeit I must cede that last one is almost as pointless as considering "free thinking."
Any programming language requires discipline to use well. If development is not performed with discipline, it will invariably result in erroneous behavior independent of the currently-available means of specifying program behavior.
One might argue that all languages and frameworks that explicitly hoist the responsibility of all matters of correctness to the developer would require the most discipline, because carelessness will most obviously result in catastrophe. In this vein, one could suggest that constructing a piece of software as a monolithic contraption in machine or assembly language would require the most discipline; after all every operation that modifies flag registers must be properly considered, every memory load and store must be reasoned in terms of both access and type correctness, and so forth.
One might argue that all languages that force the greatest amount of precision in the specification of behavior require the most discipline, because they would require the most explicit pronouncement of correctness. Every function, method, class, module, and functor would be specified in terms of exacting type-correctness and visibility. Each and every case of all variants would be properly handled in every instance of its use. The precision of type specification would include arbitrary subsets of other types. All contracts would be explicitly stated and checked for correctness on application. In especially limited design cases, memory would be exactingly allocated and done so statically.
Haskell and Objective Caml both certainly require considerable type-discipline, but neither Scheme nor Ruby does. Haskell and Objective Caml will warn about non-exhaustive pattern matching over sum types, but they do not force correctness; Ruby and Scheme do not even have sum types (which should come as no surprise when they do not have static typing), requiring hand-written reflection and runtime exceptions to provide the functionality. None of them offer compile-time checking of statically specified types that are subsets of other types. There are no hard guarantees about memory usage provided by any of the mentioned languages. None of them require concern for flag registers, but both Scheme and Ruby have a slew of type-correctness-related requirements for discipline and unit tests for things which one could argue compilers or linkers should be verifying. When dealing with modules constructed in lower-level languages, they all have woes about memory-access problems but the only relevant access problems to the discussion of discipline with respect to the language might be those that appear solely within the domain of software constructed only in the language (assuming all, if any lower-level implementation is perfectly-correct) itself, in which case the only access concerns (assuming one does not disable bounds checking with compiler flags for Objective Caml, Haskell, and your Scheme compiler) about memory access are for managing exceptions caused by broken code; not devoid of discipline requirement, but not as catastrophic as the program potentially executing undefined instructions.
These, though, are merely some examples of the real discipline that is required for designing correct software. Indeed, much of the point of the development of these languages that have been mentioned is to shift away from the discipline required from the minutiae of the first extreme, so that the discipline requi
I would like to personally peruse some of your finest examples of C++ code that you have personally written. This is to ascertain whether the implicit claim of authority from 20 years of development really has any merit.
Also, unrelated to my request, it is unfortunately the case that no platform automatically ensures that all frameworks (third-party or otherwise) are constructed with homogeneous datatypes and are free of any disjoint types that are logically congruent for some given resolution of comparison but otherwise functionally different in implementation. This though is a really an example of an issue that can appear in the form of concerns regarding the "safety" of various datatypes (proper checking of preconditions, postconditions, and invariants; proper handling and propagation of exceptions; proper specification and utilization of static type constraints; consistent guarantees of reentrancy; correctness specification that is in sync with implementation), but also matters of efficiency (consistent use of the correct datatypes for the implementation of tasks; consistent use of caching infrastructure; efficient utilization of disk, network, memory, and cache resources through reuse; efficient use of available processing and heap resources through proper specialization and avoidance of unnecessary boxing, and efficient checking of contracts), matters of maintainability (being able to decide where it is necessary to make modifications for behavior to manifest uniformly throughout the system, consistent usage and storage of logging information, being able to easily integrate new frameworks into the code base), and really a lot of other things that are beyond the scope of my interest to mention. This problem has nothing inherently to do with the development platform as such, though various languages and frameworks certainly make certain issues of correctness, efficiency, and maintainability easier to manifest, the underlying problem is still much more intrinsic to the construction of software frameworks in a heterogeneous world. You can, to some varying but limited degrees of extent, deal with issues of correctness and maintainability using the adapter pattern, but this costs both time and efficiency. Back to my point, though, Java does not solve this problem. That some C++ library may not make use of an optionally or mandatory boundary-checked collection is not terribly much different than some Java library not making consistent use of (and potentially not correctly using at all) exceptions, not even having compile-time correctness guarantees of type-safety for a collection, providing poorly-specified and unchecked preconditions, not using the correct datatype(s) for given tasks, or following consistent logging.
I am going to make an unsubstantiated claim: the person you have been engaging in discourse with is not necessarily overly knowledgeable about what they are speaking of. Any and all readers may accept or object to my claim, and that is fine; I am quite aware that I have no intention of demonstrating it with any depth.
I frankly cannot decide what precisely "free thinking" is supposed to mean in this case, but we can certainly look at discipline, and perhaps fuzzily consider the matter of "hacker language," albeit I must cede that last one is almost as pointless as considering "free thinking."
Any programming language requires discipline to use well. If development is not performed with discipline, it will invariably result in erroneous behavior independent of the currently-available means of specifying program behavior.
One might argue that all languages and frameworks that explicitly hoist the responsibility of all matters of correctness to the developer would require the most discipline, because carelessness will most obviously result in catastrophe. In this vein, one could suggest that constructing a piece of software as a monolithic contraption in machine or assembly language would require the most discipline; after all every operation that modifies flag registers must be properly considered, every memory load and store must be reasoned in terms of both access and type correctness, and so forth.
One might argue that all languages that force the greatest amount of precision in the specification of behavior require the most discipline, because they would require the most explicit pronouncement of correctness. Every function, method, class, module, and functor would be specified in terms of exacting type-correctness and visibility. Each and every case of all variants would be properly handled in every instance of its use. The precision of type specification would include arbitrary subsets of other types. All contracts would be explicitly stated and checked for correctness on application. In especially limited design cases, memory would be exactingly allocated and done so statically.
Haskell and Objective Caml both certainly require considerable type-discipline, but neither Scheme nor Ruby does. Haskell and Objective Caml will warn about non-exhaustive pattern matching over sum types, but they do not force correctness; Ruby and Scheme do not even have sum types (which should come as no surprise when they do not have static typing), requiring hand-written reflection and runtime exceptions to provide the functionality. None of them offer compile-time checking of statically specified types that are subsets of other types. There are no hard guarantees about memory usage provided by any of the mentioned languages. None of them require concern for flag registers, but both Scheme and Ruby have a slew of type-correctness-related requirements for discipline and unit tests for things which one could argue compilers or linkers should be verifying. When dealing with modules constructed in lower-level languages, they all have woes about memory-access problems but the only relevant access problems to the discussion of discipline with respect to the language might be those that appear solely within the domain of software constructed only in the language (assuming all, if any lower-level implementation is perfectly-correct) itself, in which case the only access concerns (assuming one does not disable bounds checking with compiler flags for Objective Caml, Haskell, and your Scheme compiler) about memory access are for managing exceptions caused by broken code; not devoid of discipline requirement, but not as catastrophic as the program potentially executing undefined instructions.
These, though, are merely some examples of the real discipline that is required for designing correct software. Indeed, much of the point of the development of these languages that have been mentioned is to shift away from the discipline required from the minutiae of the first extreme, so that the discipline requi
I would like to personally peruse some of your finest examples of C++ code that you have personally written. This is to ascertain whether the implicit claim of authority from 20 years of development really has any merit.
Also, unrelated to my request, it is unfortunately the case that no platform automatically ensures that all frameworks (third-party or otherwise) are constructed with homogeneous datatypes and are free of any disjoint types that are logically congruent for some given resolution of comparison but otherwise functionally different in implementation.
This though is a really an example of an issue that can appear in the form of concerns regarding the "safety" of various datatypes (proper checking of preconditions, postconditions, and invariants; proper handling and propagation of exceptions; proper specification and utilization of static type constraints; consistent guarantees of reentrancy; correctness specification that is in sync with implementation), but also matters of efficiency (consistent use of the correct datatypes for the implementation of tasks; consistent use of caching infrastructure; efficient utilization of disk, network, memory, and cache resources through reuse; efficient use of available processing and heap resources through proper specialization and avoidance of unnecessary boxing, and efficient checking of contracts), matters of maintainability (being able to decide where it is necessary to make modifications for behavior to manifest uniformly throughout the system, consistent usage and storage of logging information, being able to easily integrate new frameworks into the code base), and really a lot of other things that are beyond the scope of my interest to mention.
This problem has nothing inherently to do with the development platform as such, though various languages and frameworks certainly make certain issues of correctness, efficiency, and maintainability easier to manifest, the underlying problem is still much more intrinsic to the construction of software frameworks in a heterogeneous world.
You can, to some varying but limited degrees of extent, deal with issues of correctness and maintainability using the adapter pattern, but this costs both time and efficiency.
Back to my point, though, Java does not solve this problem. That some C++ library may not make use of an optionally or mandatory boundary-checked collection is not terribly much different than some Java library not making consistent use of (and potentially not correctly using at all) exceptions, not even having compile-time correctness guarantees of type-safety for a collection, providing poorly-specified and unchecked preconditions, not using the correct datatype(s) for given tasks, or following consistent logging.
This is not true. The type of an object can change quite easily.
class A:
def __init__(self, x):
self.x = x
def foo(self):
return self.x
class B:
def __init__(self, y):
self.y = y
def foo(self):
return self.y
a = A('d00d')
a.foo() -> 'd00d'
a.__class__ = B
a.foo() -> AttributeError