er -- by partitioning scheme, I mean the parceling out of root capabilities to a number of user accounts, each of which is responsible for (and capable of) only a portion of what we think of as root activities, along with the notion of chroot jail to limit file system visibility.
Even with sudo, if (by some means, a root kit, say) someone obtains a root shell, the system is at that moment totally vulnerable.
The idea behind the partitioning setup is that each exploit only grants access to a *part* of the system -- specifically the parts that the particular rootlet has access to. Using chroot for servers even partitions the file system limiting visibility to data.
IMHO the idea is a good one. It doesn't even make systems more difficult to setup/administer, if well done.
UTC vs GMT (slightly off-topic)
on
Why not Ruby?
·
· Score: 2
While it is true that UTC is not GMT, they are close enough to each other for nearly all practical purposes in a programming context. If you are handling astronomical or navigational data, you will care about the differences, but otherwise, probably not.
I should also note that there are two UTC definitions. These days, when we say UTC, we usually mean UTC2, which is based on atomic clocks. Both GMT and UTC(1) are based on astronomical observations, with UTC(1) compensating for some local variations. Generally speaking, the differences ammount to not more than a few seconds.
Time zones are civil structures, where UTC/GMT times are really observations. Thus, time zone handling can be nearly irrational (after all, civil law makers were involved). In this context, using the observable time for all internal comparisons/storage/calculations makes a great deal of sense. This relegates time zones to input/output, which makes almost everything much simpler. You just need to remember that the hours value in the object is probably UTC, with the zone retained only for convenience.
Having said that, I'll note that the usual abbreviations for time zones are not unique, world wide, with some 3-letter abbreviations being used for several zones that are widely separated geographically. An additional complication comes from the various rules for going to/from daylight savings times.
If you were not already convinced, UTC is far simpler to use and stay sane with, and that is totally independent of your language of choice.
From what I understand, yes, it did something very much like that for something like 18 months.
There is a very good book on the history of AI written about 5 years ago (maybe longer) that described Cyc, and Lenat's research up leading up to it, along with the contributions of a great many others. Unfortunately, the volume is sitting on my AI/Math/Computer Science bookcase at home, and I can't remember either the title or author:(
I must humbly disagree. If we suddenly had acess to some non- von Neumann architecture machine, everyone who worked on it would have much rethinking to do, especially since our notions of complexity -- and therefore our notions of what makes a good algorithm -- are all rooted in the idea of serial execution of a stored program, threading notwithstanding. Even fine-grain parallel machines are just collections of serial execution machines.
I have worked with people in the past who insisted that particular machine details are unimportant. For instance, they would say "There is no need to worry about the cost of paging due to a large resident memory set -- just buy more memory!" And then it would occur that we'd maxed out physical memory on that generation of machine -- response was -- "wait -- memories will be bigger next year." Memory did get bigger, but by the time memory was large enough, we were out of business.
Ignoring the machine does not solve a problem here. Ignoring people will definately cause a problem, though, as you observe. Therefore the solution (it seems to me) is to teach more -- not less. Teach good user interface practices in addition to teaching how the machine works.
After carefully reading the project page link, I think the author over at wired missed the point entirely. FiberOptics are glass -- low tensile strength, while the core of a transmission line's primary purpose is to provide load carrying capacity in tension. Thus, using fiber optic cable for a transmission line core makes no sense.
On the other hand -- recent advances in carbon composites have resulted in some amazingly good fibers with strength/weight ratios that are hard to believe. Replacing the steel core with carbon composite fibers would allow more current carrying aluminium in the same diameter cable.
The splicing question now makes much more sense -- splicing metal cables is a simple mechanical proposition -- not so with joining composites.
OTOH, the substitution is not perfect. As cool as perl modules are, they do not give you new syntax, while lisp macros can. Splicing, backquote, reader macros are enough to totally transform the language to an entirely different thing.
are you certain of that? I seem to recall some clever transformations that will result in the exactly the rewrite you suggest. Scheme compilers wont to do the rewrite, IIRC, but i;m nearly certain that Lucid Common LISP would do the transform with a high enough optimization level.
On the other hand, that was at *least* 7 years ago, and those brain cells may already be demented -heh
and don't forget that the LISP compiler is likely to rewirite your code using tail-recursion elimination, making the recursive calls into a loop, along with some obvious variable transformations, leading to code which is obvious and correct and also effecient.
I assume you meant dynamic _extent_, by which bindings for variables can change in a controlled fashion. The binding is guaranteed to be restored to its former state as the function frame that created it exits. This is a GOOD THING, properly used.
OTOH -- both languages are useful. I'd learn both. Oh -- wait -- I did...:)
LISP is so flexible that the rewrites you talk about improve the program over time rather than making things works, provided that the programmer thinks rather than just slinging code. There is a moment when you look at the code, thinking about implementing some new feature, and your head explodes -- you suddenly realize that you can discard several hundred lines in various places with a new abstraction -- a macro or maybe a just a new function....
I write C++ most of the time to work with an existing code base, but I use LISP every chance i get.
the implementation model of elisp is simpler than CL, and is missing a number of really useful features, while retaining one really bad feature.
elisp is derived from LISP 1.5 and MACLISP, IIRC.
The ugly feature is dynamic scope -- all variables in all functions on the stack are visible for modification. *shudder*.
The present in CL that are missing in elisp are almost too numerous to mention, but some simple elements of syntax like do and loop, and lexical scope, come to mind.
I challenge you to write an effecient planning package in Haskell. While I love functional purity, monads do not come close to providing the conceptual utility of Classes or some similarly clear representation of concepts, unless things have changed a *lot* in the last 5 years (since I last studied Haskell....)
Yes I know about the newer compilers. You will soon hit the wall:)
um -- that depends on the quality of those hundred other programmers. If you have separable packages, OK. I'm guessing that a package one or 5 people would consider tackling does not read like that, so you suffer communication problems, and the lack of skill so often displayed by the average programmer. Interoperability becomes a problem too -- someone has to glue all that junk together.
My advice is to choose the supporting libraries *very* carefully.
no -- *you* missed the point. The idea is that a more powerful language has some feature Y that has these properties:
(1) Y can't be replicated in a lower level language with out changing the language, or without lots of programming to simulate the feature, and that the programming does not yield a library.
(2) Programmers who don't know about Y don't miss it because they can accomplish their goals without it, but the goals are lower than they might be otherwise.
There are many such properties. GC, Macros, Recursion, continuations, closure, type inference, generic fuctions, templates, multiple inheritance, message passing, etc., etc.
This yields a partial ordering of languages in terms of expressive power.
Because LISP is so close to the lambda calculus (that was the motivation for writing it in the first place, btw), and because the code is also data, you can build up any abstraction you like as a component of the language. This yields a language that ranges from really low level computationally, to really, really abstract, to really close to the problem you want to solve. It is that last property that makes lisp programming so powerful. Invent a new property Y. You can almost certainly emulate/simulate it directly in LISP -- then refine your LISP implementation for better OS interface or what ever, you're done.
Consider implementing multimethod dispatching in C++. I dare you. It is *hard* to get right. There is not enough in the way of introspection in the language to make it work.
It is not *easy* in lisp, but it has been done, and it works. It is not a tool for everything, but there are problems for which there is no better techniques. thus LISP is more powerful than C++. QED.
well yes, but they were looking for a particular type of other person to work with -- and that type of person either knows lisp, or wants to learn lisp. LISP has the hacker nature -- that quality that leads to being 100 times more productive than the average VB programmer.
Actually having used LISP and C++ (along with many other languages) in my career, I can speak with *some* authority on the differences. I'm frequently astonished with people who express opinions about some language with out first learning something about it. People seem to learn only some small corner of a language and assume the rest of the language is like that chunk, or worse, latch on to some half formed opinion expressed by some other person, and claim that to be the final word on the language.
The saddest reality is that there is a 100:1 productivity ratio among programmers, and there are many more at the low end than at the high end. I have noticed that the best programmers all know LISP. They grok LISP. As a result, they *really* understand computation deeply enough for that understanding to translate to any other language, though it still takes time to grok the core idea of that other language (C++ comes to mind as a devilishly complex language to truely master).
Every language has a core quality that the programmer must grasp to use the language effectively. If you can't learn that core idea, the game is over.
So -- when you say that the code is being rewritten in C++ because your shop can't maintain it, what you are saying is that you can't understand the elegant design, so you will replace it with something simpler (you hope), and will ultimately find that the resulting program is far more brittle, and harder to maintain.
You are also saying that you don't have any of those programmers who truely grok computation.
As support for my position: I developed software for engineering automation in the 80's and 90's, then moved to control systems when my company was sold and destroyed by poor management. Technically, the product (written in CommonLISP) was a screaming success. We just could not make good sales/management/investment decisions. I now write control system software in C++. LISP would work better, but I needed to be compatable with an existing code base. I consider myself to be expert or at least competent in both languages.
LISP is not that hard to learn, by the way. The syntax is *really* simple, the language uniform. What *really* stalls people is not the parens or the effeciency, or loose typing (as is often reported), the core problem people choke on is the abstraction. If your mind is not well enough trained to understand the idea of mapping a function over a domain and expressing that directly, rather than say as a looping procedure, or if you can't grasp recursion, you can't really pick up speed, and when you read code that uses those ideas, you will be lost entirely.
We could all stand to learn much more. Study LISP -- it will improve your programming skills hugely, I promise you.
Well, you are right that I was digging at Windows. I've been astonished at certain types of thinking about program construction that is directly attributable to exposure to Windows and/or MFC. (I usually refer to that thinking as Windows/MFC-induced brain damage) It seems to me that the sloppy thinking occured when those interfaces were constructed (I don't imagine that they were designed....), but the effects carry forward to anyone who learns to program by being exposed to them.
But that was not the point of my post, really. I just like take every opportunity to point out the flaws of the MFC/Windows programming model.;-)
You can use GC to cover up design flaws, just as you can misuse any feature of any language. The mere presence of GC in a design does not indicate sloppy thinking. It might. Or -- the presence of GC might indicate that the objects modeled have such indeterminate lifetimes that GC is the best solution to managing them. Before you rant on *that* being a result of sloppy thinking, consider the semantic nets I mentioned above -- they deal with real world data that is changing over time, and it is not clear when a node is no longer useful untill the last reference is lost or dropped. If the semantic net is multi-type, you might have a serious problem keeping up with the reference management, particularly when there are multiple referents, and no clear hierarchy. GC expresses memory management well under these circumstances.
I'm not saying that GC is the only solution here -- clearly reference counting would work, but it tends to obscure the code and has limitations (e.g. circular structures). IMHO, GC is the best engineering solution to that type of memory management problem.
Adding GC as an *option* to the language just gives me another useful tool. Your tool box can never be too full.
Well -- the other way to handle this is to use a class to manage the connection. Create a class to manage the DB connection, and have this class do the grunt work of creating or obtaining the DB connection. This can be done in the constructor or in some member function (more likely in the code you gave above). Also have the destructor close or return the connection. The class should also be able to handle the case where no connection is available correctly.
If the instance is allocated on the stack, you'll get the connection cleaned up when you leave that scope. This does everything that the finally would have done, and the class will be usable in other locations -- a great help in the example you give, since the pattern is likely somewhat common in your app.
This is a really old idea, btw -- it was mentioned in the first edition of "The C++ Programming Language", IIRC.
All useful languages that I am familiar with are also equivalent to some Turing machine. You can always write a transformation to a Turing machine description (not that it would be *easy* -- they don't call it the Turing-tar-pit for no reason:). In turn, you can always write a transformation from a turing machine description to a common processor type machine (loosing infinite tapes in the process, but that is no real loss, since the original program has that same limit).
So -- I contend that you can compile *any* computer language that you can interpret. The only question that remains is whether compilation is useful for the language in question.
You presume too much. To my way of thinking, Java has some serious flaws that could have been avoided. Others have mentioned VM and the lack of independent standards -- I'm not so concerned about those.
What bothers me about Java are these two things:
(1) The thread primitives are not primitive enough. Per Brinch Hanson and C.A.R. Hoare demonstrated the minimum requirements for correct threading 30 years ago (IIRC) - the library implementation in Java leaves open some very hard to track down race conditions (Note that the fact that you have not seen the problem only means that you have not triggered the problem).
(2) Interfaces cannot contain code, so cannot provide behaviour. Multiple inheritance is prohibited (Yes MI is hard to get right, but sometimes it *is* the right tool for the job, with all alternatives being inferior). This leads to duplication of what should be common code.
Language design is really hard to get right, so there can be no guarantee of continued progress. Some new ideas will turn out to be really bad ideas. We have to try things out and see how they work in practice. I'm fairly certain that every language will be less than perfect because of the cognitive distance between how humans think and how computers work. What makes a programming wizard so amazingly productive is (imho) a well trained mind, and the ability to *really* focus on a single task.
Geez -- I haven't often seen such ignorance displayed with such force. You really ought to consider doing some reading on GC as a topic, and not rely on (I'm guessing:) experience with one really bad implementation.
Properly implemented, GC has no impact on the classes interface, or even the lifetime of the objects. What it does accomplish is to allow the designer to concentrate on the problem semantics and ignore object lifetimes. There are real problems where this is a serious issue, and where you cannot design the problem away without implementing reference counting or some other poor cousin of GC. Semantic nets, and related AI type problems tend to have this characteristic.
And no -- sloppy thinking does not result in GC, it results in Windows applications.
The problem with getting a proper implementation is that GC would like to know the types of things in much more detail than the compiler ordinarily makes known to the runtime system. If all obects had RTTI type information, then GC is much easier to implement in a clear and correct way. If the standard prescribed hooks allowing implementations to provide GC, then we'd have it when we need it without lots of extraneous effort. G++ has one such facility.
In the circles of political discourse, as filtered through the national media in the US, extreme views on both sides get more press (in general) than moderate views because extremeism makes better copy -- it gets people riled up. This is true to a large degree of both the left and right.
The NRA sounds radical because you generally only hear the radicalized version of things. The same could be said of the gun-control people (I'm hard pressed to name even a single such group, in spite of the fact that there are several -- my own ignorance, possibly willful).
There are right wing loonies in the NRA. Not every NRA member is one such. They do all like guns, however.
The NRA defends the right of people to bear arms, as guaranteed in our constitution. This is reasonable. That provision is not really there for hunters -- it exists because we as a people have historically had a profound distrust of government, prefering to keep it close to us, where we can watch it carefully. The authors also had recent experience with governments confiscating arms and property for its own use.
Aerogels are mostly air -- a foam or sponge of Si and other junk with some intert gas in the cells/holes, while these fibers are mostly glass, and the holes are really tubes that run the length of the fiber in a very regular pattern. So, you see that the structure of these two things are totally unrelated.
er -- by partitioning scheme, I mean the parceling out of root capabilities to a number of user accounts, each of which is responsible for (and capable of) only a portion of what we think of as root activities, along with the notion of chroot jail to limit file system visibility.
:)
I should read more carefully
Even with sudo, if (by some means, a root kit, say) someone obtains a root shell, the system is at that moment totally vulnerable.
The idea behind the partitioning setup is that each exploit only grants access to a *part* of the system -- specifically the parts that the particular rootlet has access to. Using chroot for servers even partitions the file system limiting visibility to data.
IMHO the idea is a good one. It doesn't even make systems more difficult to setup/administer, if well done.
While it is true that UTC is not GMT, they are close enough to each other for nearly all practical purposes in a programming context. If you are handling astronomical or navigational data, you will care about the differences, but otherwise, probably not.
:)
I should also note that there are two UTC definitions. These days, when we say UTC, we usually mean UTC2, which is based on atomic clocks. Both GMT and UTC(1) are based on astronomical observations, with UTC(1) compensating for some local variations. Generally speaking, the differences ammount to not more than a few seconds.
Time zones are civil structures, where UTC/GMT times are really observations. Thus, time zone handling can be nearly irrational (after all, civil law makers were involved). In this context, using the observable time for all internal comparisons/storage/calculations makes a great deal of sense. This relegates time zones to input/output, which makes almost everything much simpler. You just need to remember that the hours value in the object is probably UTC, with the zone retained only for convenience.
Having said that, I'll note that the usual abbreviations for time zones are not unique, world wide, with some 3-letter abbreviations being used for several zones that are widely separated geographically. An additional complication comes from the various rules for going to/from daylight savings times.
If you were not already convinced, UTC is far simpler to use and stay sane with, and that is totally independent of your language of choice.
have a nice day
From what I understand, yes, it did something very much like that for something like 18 months.
:(
There is a very good book on the history of AI written about 5 years ago (maybe longer) that described Cyc, and Lenat's research up leading up to it, along with the contributions of a great many others. Unfortunately, the volume is sitting on my AI/Math/Computer Science bookcase at home, and I can't remember either the title or author
I must humbly disagree. If we suddenly had acess to some non- von Neumann architecture machine, everyone who worked on it would have much rethinking to do, especially since our notions of complexity -- and therefore our notions of what makes a good algorithm -- are all rooted in the idea of serial execution of a stored program, threading notwithstanding. Even fine-grain parallel machines are just collections of serial execution machines.
I have worked with people in the past who insisted that particular machine details are unimportant. For instance, they would say "There is no need to worry about the cost of paging due to a large resident memory set -- just buy more memory!" And then it would occur that we'd maxed out physical memory on that generation of machine -- response was -- "wait -- memories will be bigger next year." Memory did get bigger, but by the time memory was large enough, we were out of business.
Ignoring the machine does not solve a problem here. Ignoring people will definately cause a problem, though, as you observe. Therefore the solution (it seems to me) is to teach more -- not less. Teach good user interface practices in addition to teaching how the machine works.
Hmmm, you're right about the higher elasticity of fiberglass, now that I think about it.
OTOH, we'd still talking about fiberglass composites rather than the types of glass we use for optics, IIRC.
After carefully reading the project page link, I think the author over at wired missed the point entirely. FiberOptics are glass -- low tensile strength, while the core of a transmission line's primary purpose is to provide load carrying capacity in tension. Thus, using fiber optic cable for a transmission line core makes no sense.
On the other hand -- recent advances in carbon composites have resulted in some amazingly good fibers with strength/weight ratios that are hard to believe. Replacing the steel core with carbon composite fibers would allow more current carrying aluminium in the same diameter cable.
The splicing question now makes much more sense -- splicing metal cables is a simple mechanical proposition -- not so with joining composites.
That's pretty funny.
OTOH, the substitution is not perfect. As cool as perl modules are, they do not give you new syntax, while lisp macros can. Splicing, backquote, reader macros are enough to totally transform the language to an entirely different thing.
are you certain of that? I seem to recall some clever transformations that will result in the exactly the rewrite you suggest. Scheme compilers wont to do the rewrite, IIRC, but i;m nearly certain that Lucid Common LISP would do the transform with a high enough optimization level.
On the other hand, that was at *least* 7 years ago, and those brain cells may already be demented -heh
and don't forget that the LISP compiler is likely to rewirite your code using tail-recursion elimination, making the recursive calls into a loop, along with some obvious variable transformations, leading to code which is obvious and correct and also effecient.
I assume you meant dynamic _extent_, by which bindings for variables can change in a controlled fashion. The binding is guaranteed to be restored to its former state as the function frame that created it exits. This is a GOOD THING, properly used.
:)
OTOH -- both languages are useful. I'd learn both. Oh -- wait -- I did...
ROFL -- you have never groked LISP, have you?
LISP is so flexible that the rewrites you talk about improve the program over time rather than making things works, provided that the programmer thinks rather than just slinging code. There is a moment when you look at the code, thinking about implementing some new feature, and your head explodes -- you suddenly realize that you can discard several hundred lines in various places with a new abstraction -- a macro or maybe a just a new function....
I write C++ most of the time to work with an existing code base, but I use LISP every chance i get.
the implementation model of elisp is simpler than CL, and is missing a number of really useful features, while retaining one really bad feature.
elisp is derived from LISP 1.5 and MACLISP, IIRC.
The ugly feature is dynamic scope -- all variables in all functions on the stack are visible for modification. *shudder*.
The present in CL that are missing in elisp are almost too numerous to mention, but some simple elements of syntax like do and loop, and lexical scope, come to mind.
I challenge you to write an effecient planning package in Haskell. While I love functional purity, monads do not come close to providing the conceptual utility of Classes or some similarly clear representation of concepts, unless things have changed a *lot* in the last 5 years (since I last studied Haskell....)
:)
Yes I know about the newer compilers. You will soon hit the wall
um -- that depends on the quality of those hundred other programmers. If you have separable packages, OK. I'm guessing that a package one or 5 people would consider tackling does not read like that, so you suffer communication problems, and the lack of skill so often displayed by the average programmer. Interoperability becomes a problem too -- someone has to glue all that junk together.
My advice is to choose the supporting libraries *very* carefully.
no -- *you* missed the point. The idea is that a more powerful language has some feature Y that has these properties:
(1) Y can't be replicated in a lower level language with out changing the language, or without lots of programming to simulate the feature, and that the programming does not yield a library.
(2) Programmers who don't know about Y don't miss it because they can accomplish their goals without it, but the goals are lower than they might be otherwise.
There are many such properties. GC, Macros, Recursion, continuations, closure, type inference, generic fuctions, templates, multiple inheritance, message passing, etc., etc.
This yields a partial ordering of languages in terms of expressive power.
Because LISP is so close to the lambda calculus (that was the motivation for writing it in the first place, btw), and because the code is also data, you can build up any abstraction you like as a component of the language. This yields a language that ranges from really low level computationally, to really, really abstract, to really close to the problem you want to solve. It is that last property that makes lisp programming so powerful. Invent a new property Y. You can almost certainly emulate/simulate it directly in LISP -- then refine your LISP implementation for better OS interface or what ever, you're done.
Consider implementing multimethod dispatching in C++. I dare you. It is *hard* to get right. There is not enough in the way of introspection in the language to make it work.
It is not *easy* in lisp, but it has been done, and it works. It is not a tool for everything, but there are problems for which there is no better techniques. thus LISP is more powerful than C++. QED.
well yes, but they were looking for a particular type of other person to work with -- and that type of person either knows lisp, or wants to learn lisp. LISP has the hacker nature -- that quality that leads to being 100 times more productive than the average VB programmer.
Actually having used LISP and C++ (along with many other languages) in my career, I can speak with *some* authority on the differences. I'm frequently astonished with people who express opinions about some language with out first learning something about it. People seem to learn only some small corner of a language and assume the rest of the language is like that chunk, or worse, latch on to some half formed opinion expressed by some other person, and claim that to be the final word on the language.
The saddest reality is that there is a 100:1 productivity ratio among programmers, and there are many more at the low end than at the high end. I have noticed that the best programmers all know LISP. They grok LISP. As a result, they *really* understand computation deeply enough for that understanding to translate to any other language, though it still takes time to grok the core idea of that other language (C++ comes to mind as a devilishly complex language to truely master).
Every language has a core quality that the programmer must grasp to use the language effectively. If you can't learn that core idea, the game is over.
So -- when you say that the code is being rewritten in C++ because your shop can't maintain it, what you are saying is that you can't understand the elegant design, so you will replace it with something simpler (you hope), and will ultimately find that the resulting program is far more brittle, and harder to maintain.
You are also saying that you don't have any of those programmers who truely grok computation.
As support for my position: I developed software for engineering automation in the 80's and 90's, then moved to control systems when my company was sold and destroyed by poor management. Technically, the product (written in CommonLISP) was a screaming success. We just could not make good sales/management/investment decisions. I now write control system software in C++. LISP would work better, but I needed to be compatable with an existing code base. I consider myself to be expert or at least competent in both languages.
LISP is not that hard to learn, by the way. The syntax is *really* simple, the language uniform. What *really* stalls people is not the parens or the effeciency, or loose typing (as is often reported), the core problem people choke on is the abstraction. If your mind is not well enough trained to understand the idea of mapping a function over a domain and expressing that directly, rather than say as a looping procedure, or if you can't grasp recursion, you can't really pick up speed, and when you read code that uses those ideas, you will be lost entirely.
We could all stand to learn much more. Study LISP -- it will improve your programming skills hugely, I promise you.
Well, you are right that I was digging at Windows. I've been astonished at certain types of thinking about program construction that is directly attributable to exposure to Windows and/or MFC. (I usually refer to that thinking as Windows/MFC-induced brain damage) It seems to me that the sloppy thinking occured when those interfaces were constructed (I don't imagine that they were designed....), but the effects carry forward to anyone who learns to program by being exposed to them.
;-)
But that was not the point of my post, really. I just like take every opportunity to point out the flaws of the MFC/Windows programming model.
You can use GC to cover up design flaws, just as you can misuse any feature of any language. The mere presence of GC in a design does not indicate sloppy thinking. It might. Or -- the presence of GC might indicate that the objects modeled have such indeterminate lifetimes that GC is the best solution to managing them. Before you rant on *that* being a result of sloppy thinking, consider the semantic nets I mentioned above -- they deal with real world data that is changing over time, and it is not clear when a node is no longer useful untill the last reference is lost or dropped. If the semantic net is multi-type, you might have a serious problem keeping up with the reference management, particularly when there are multiple referents, and no clear hierarchy. GC expresses memory management well under these circumstances.
I'm not saying that GC is the only solution here -- clearly reference counting would work, but it tends to obscure the code and has limitations (e.g. circular structures). IMHO, GC is the best engineering solution to that type of memory management problem.
Adding GC as an *option* to the language just gives me another useful tool. Your tool box can never be too full.
Well -- the other way to handle this is to use a class to manage the connection. Create a class to manage the DB connection, and have this class do the grunt work of creating or obtaining the DB connection. This can be done in the constructor or in some member function (more likely in the code you gave above). Also have the destructor close or return the connection. The class should also be able to handle the case where no connection is available correctly.
If the instance is allocated on the stack, you'll get the connection cleaned up when you leave that scope. This does everything that the finally would have done, and the class will be usable in other locations -- a great help in the example you give, since the pattern is likely somewhat common in your app.
This is a really old idea, btw -- it was mentioned in the first edition of "The C++ Programming Language", IIRC.
All useful languages that I am familiar with are also equivalent to some Turing machine. You can always write a transformation to a Turing machine description (not that it would be *easy* -- they don't call it the Turing-tar-pit for no reason :). In turn, you can always write a transformation from a turing machine description to a common processor type machine (loosing infinite tapes in the process, but that is no real loss, since the original program has that same limit).
So -- I contend that you can compile *any* computer language that you can interpret. The only question that remains is whether compilation is useful for the language in question.
You presume too much. To my way of thinking, Java has some serious flaws that could have been avoided. Others have mentioned VM and the lack of independent standards -- I'm not so concerned about those.
What bothers me about Java are these two things:
(1) The thread primitives are not primitive enough. Per Brinch Hanson and C.A.R. Hoare demonstrated the minimum requirements for correct threading 30 years ago (IIRC) - the library implementation in Java leaves open some very hard to track down race conditions (Note that the fact that you have not seen the problem only means that you have not triggered the problem).
(2) Interfaces cannot contain code, so cannot provide behaviour. Multiple inheritance is prohibited (Yes MI is hard to get right, but sometimes it *is* the right tool for the job, with all alternatives being inferior). This leads to duplication of what should be common code.
Language design is really hard to get right, so there can be no guarantee of continued progress. Some new ideas will turn out to be really bad ideas. We have to try things out and see how they work in practice. I'm fairly certain that every language will be less than perfect because of the cognitive distance between how humans think and how computers work. What makes a programming wizard so amazingly productive is (imho) a well trained mind, and the ability to *really* focus on a single task.
Geez -- I haven't often seen such ignorance displayed with such force. You really ought to consider doing some reading on GC as a topic, and not rely on (I'm guessing :) experience with one really bad implementation.
:)
Properly implemented, GC has no impact on the classes interface, or even the lifetime of the objects. What it does accomplish is to allow the designer to concentrate on the problem semantics and ignore object lifetimes. There are real problems where this is a serious issue, and where you cannot design the problem away without implementing reference counting or some other poor cousin of GC. Semantic nets, and related AI type problems tend to have this characteristic.
And no -- sloppy thinking does not result in GC, it results in Windows applications.
The problem with getting a proper implementation is that GC would like to know the types of things in much more detail than the compiler ordinarily makes known to the runtime system. If all obects had RTTI type information, then GC is much easier to implement in a clear and correct way. If the standard prescribed hooks allowing implementations to provide GC, then we'd have it when we need it without lots of extraneous effort. G++ has one such facility.
hope this educates you a little
In the circles of political discourse, as filtered through the national media in the US, extreme views on both sides get more press (in general) than moderate views because extremeism makes better copy -- it gets people riled up. This is true to a large degree of both the left and right.
The NRA sounds radical because you generally only hear the radicalized version of things. The same could be said of the gun-control people (I'm hard pressed to name even a single such group, in spite of the fact that there are several -- my own ignorance, possibly willful).
There are right wing loonies in the NRA. Not every NRA member is one such. They do all like guns, however.
The NRA defends the right of people to bear arms, as guaranteed in our constitution. This is reasonable. That provision is not really there for hunters -- it exists because we as a people have historically had a profound distrust of government, prefering to keep it close to us, where we can watch it carefully. The authors also had recent experience with governments confiscating arms and property for its own use.
uh -- no.
Aerogels are mostly air -- a foam or sponge of Si and other junk with some intert gas in the cells/holes, while these fibers are mostly glass, and the holes are really tubes that run the length of the fiber in a very regular pattern. So, you see that the structure of these two things are totally unrelated.
hth