Threads introduce non-deterministic interactions between different parts of a program. This can make adequate testing a pain.
Actually, this means XP testing (with its focus on unit testing) works very well when compared to the traditional "testing" model of code, run, visually-inspect. If you're getting a goofed up result from an operation, and the unit tests for each of its parts pass, you know you've got problem that's a result of the joining of the parts. In this case, the problem inside "joining of the parts" is most likely the concurrency.
If you have a terribly coupled model where the thread-spawning code is mixed in with the code that does real work, then I suppose I can see how it could get difficult to test. However, part of XP's design principles are to do things "Once and Only Once", so this type of code would be frowned upon even if it didn't make testing difficult.
If they can't find a way to make it work with threading, XP has some serious flaws.
Can you clarify that any? I must be missing something, because I cannot fathom how XP has any problems with threading.
GUI unit testing is a trick, but a common point of discussion on XP forums. It's doable in any of several dozen ways. From what I can tell, the only problem is that no one GUI testing practice has emerged as the best.
However, pretty much every day,
someone stupid would destroy her code
under the guise of XP's constant state
of refactoring.
Do you mean they broke its design,
its style, or its functionality?
If you're referring to the design,
then it is possible that your girlfriend
is from the "old skool" of OOP --
overdesign everything and make
everything conform to a particular
arbitrary set of rules.
I don't mean that to sound insulting
-- I used to be the same way. My
coworkers changing my code was a
constant annoyance because they would
stomp all over my little flower garden.
In retrospect, however, many of the
changes that were made were good -- very
simple, very clean. I was determined
that good code should be uber general.
If you are referring to the coding
styles and such -- that means that the
team wasn't doing XP, because XP
involves a coding standard. When I
first saw that having a coding standard
was one of the XP practices,
I thought it odd and overly specific.
But it is necessary to fit in with the
XP practice of "collective ownership" of
all code.
If they broke the functionality...
well, then why wasn't there a unit test
written? The avid unit testing of XP is
one of the most visibly enjoyable
aspects of the methodology.
Traditionally, writing regression tests
is a burden.
Beck and others have
noticed how much better/faster/more
confidently code can be developed if the
unit tests are written before the units
are implemented. You then implement
until all the tests pass, and then
you're done.
However, even if you're doing test-first
programming like that, breakage will
occasionally occur. But when things do
break, you have to try to figure out
(and write!) a test that could've
ensured that the breakage wouldn't have
happened. Eventually, (or so I've
heard), you learn how to test well
enough that you don't have this problem
nearly ever.
Remember what ol' Kent Beck says about
XP: "80% of the benefit comes from
following the last 20% of the
practices". In other words, if you are
doing nine out of the twelve practices,
you're probably only seeing 20% of the
benefit. As soon as you plug in those
last three is as soon as you'll see the
biggest benefit of the methodology.
Of course, my diagnosis could've been
completely wrong here -- I'm just taking
some guesses.
"When I'm working on a problem, I never think about beauty. I think only how
to solve the problem. But when I have finished, if the solution is not
beautiful, I know it is wrong." -- Buckminster Fuller
translate any characters other than "a-z" (case-insensitive), "0-9", and "$" to newlines -- I.e., split everything up onto its own line.
sed -n -e 's/\(\$[0-9]+\)/<BR>&/p'
Then "grep" for dollar amounts, outputting them with HTML <br>'s so that they can easily be pasted into the/. form.
Fraud detector (patent applied for)
The joke is that there are a lot of dollar amounts mentioned in the TOS, which makes it sound a little fraudish. He wrote a shell pipeline to automatically extract dollar amounts from a document, which will give an indication of how much the author is interested in money.
Anyhow, security was just an example. Suppose your first draft of the source code is just poorly formatted and doesn't have enough comments? Maybe you don't want everybody to get a bad first impression.
I'm also a little lost as to the logic of your post. You start off talking about security, and then start talking about bugs. These are very different things.
Not usually. Look at any of the security boards... my estimate is that 80% of security holes are related to simple bugs, with the remaining 20% being architectural flaws.
If it is a simple bug, then my previous post applies -- why should it exist at all? If it is some deeper, "archetectural" level security issue, then it should certainly not be held secret with an insecure binary being released.
I can't imagine a person willfully advocating the release of an insecure binary without source for the purposes of fixing the insecurities in the background.
3.... Suppose you write an initial version that is full of security holes, but that does demonstrate some key functionality. You might want to release a binary, then spend a month fixing the security, then open-source the project.
Oof. That's a very foolish thing to advise. Though I am not the first to rant against "Security through Obscurity", I'm going to have to speak against this one for sure.
Just so I get this straight... you're advocating giving a person a binary with security holes, and not informing them (either through source or English description) what those holes are? That's so absurd!
I am guessing that you are unaware of such tools as strace and ltrace, which would most likely leave the security hole in plain view, anyway.
But that's not even the half of it.
My real question is this: Why are the bugs there in the first place?
I am absolutely tired of buggy software. It should be (and as far as I'm concerned, is) a thing of the past. I am unable to understand why a person would write a line of buggy code, unless of course they don't understand how that can be done.
The idea is that you develop in micro-iterations... every time you want to add a feature, you write a test first, then you implement the interface until the tests all pass. When you are done, you have the guarantee that everything works, and that it will continue to work (because you never remove the test).
Other XP tenets that would very much help here are:
I have a good guess as to what your first rebuttal is going to be, "But what about experimental features?", as in features that are prototypical. In this case the practice of Spike Solutions becomes relevant.
None of this is just kooky theories. Well, they are that =)... but they're more -- people (including myself) are actually doing this and it is working. Since I've begun my adoption of the XP process, I've developed better code that is nearly 100% bug free at the end of each iteration, and I've developed it faster.
I realize that I linked more than I spoke, but I feel that the XP practices speak for themselves against the mindsets that I'm seeing in yours and other posts.
12 sales out of 1308? Not bloody likely. The accepted statistic is 1 sale out of 1000 visitors and that statistic doesnt even take into account the 30% chargeback margin due to rampant credit card fraud.
Sorry, but it appears that you are spouting all these statistics based on your experience with porn sites.
Having worked for a company providing online stores for legitimate businesses (Ie, non-porn), I can say that it is very normal for there to be a >1% conversion rate. In addition, credit card fraud was an issue that seldom arose.
Matter of fact, the folks in charge of promoting the store always felt like %1 was a terrible number, and wanted to beat it.
I'd bet you can make a lot of errors by applying porn-site statistics to more general areas. (This just in!: Studies show 100% of web sites attempt to disable the back button via JavaScript.)
Yes, and all these things sadden me to some degree. I cut my teeth on Perl, and
it's unfortunate for me to have to look back on the language of my youth as a "toy-language". I'll always use it as a day-to-day tool, but I must say that this project forever cured me of using any predominantly dynamically typed language for a lorge project.
I understand that Perl's purpose was never to be like C++ or Java, but I get the feeling that the perl interpreter is too busy trying to "please", accepting whatever I give it. Twistng Larry's quote about false laziness and such, I consider it "false postmodernism".
I certainly don't mean to say my $user = new UnprivilegedUser; $user->destroyTheWholeSystem(), and I would like some help from the interpreter to remind me when I try. Unless some sort of "use TypeCheck" pragma could be introduced, I see this whole thing as a death toll for Perl's use on a large/multi-developer project in exchange for a little niftiness in a few obscure situations.
As the author of a 'big project' in Perl, I have to adamantly disagree. It's not Perl's fault. There are some languages that cuff you about the head and shoulders with a club and force you out of your 'random and unplanned' style, but not Perl. If you're an undisciplined programmer from the get go, Perl won't help you.
And as a member of a 'big project' in Perl (nearing 100k lines, ~10 full-time developers), I have to adamantly agree with the original poster.
You are right in saying that there are programming practices that other languages pretty much force you to use that Perl doesn't. This brings me to point #1:
Sometimes peole need "pushes" in the right direction. Not everyone will factor designs as elegantly as you would wish, and there are times when it's too tempting to get out a hack solution. Regardless of what theoretical arguments there are against this, I have seen it happen in practice over and over.
Perl gives a person a lot of control over primitives (strings, hashes, arrays). This is a great benifit in many uses, for example "perl -pi -e", being the most useful implementation of a "read/write grep" I can imagine. However, because it is so easy to pass primitives around, more sophisticated, abstracted types are seldom used. This can be overcome if every developer on the project is a very disciplined OO programmer, but even then Perl's object model is so much harder to use than, say, C++'s. Which brings me to point #2:
There are insurmountable problems in Perl's design that lead to too many things being checked at run-time.
For example, say I want to make a function that only accepts objects of a base type "AdminUser", how can I make sure that an object of type "UnprivilegedUser" doesn't get passed? Perl's answer: Run-time checks.
The simple case is when I wrote an obvious bug and the program will choke upon the first running. The less-simple case is when the code works under most statesduring debugging, but running it in a production environment causes some before-un-thought-of state to surface. Then, we have production code crashing. Or, worse, we have unprivileged users with admin rights in some cases. Suck.
In C++, I would've had a compile(or link)-time error raised explaining to me the situation. I highly question the value of being able to change classes at run-time anyway. Sure, folks like Damien Conway can make some tricky libraries, but beyond that reinventing the object model every time you write a class is a pain.
Please understand that this is *not* a strawman argument, as most of the hours in my day for the last six months have been spent debugging the above problem. It's also why I'm deeming this the last Perl project that I will ever work on.
Both the "C pointer model" and the manual memory management are easily wrappable.
They are wrappable only in special cases. They are not wrappable in general. For example, you can't "wrap" call-by-reference or the address-of operator because smart pointers aren't really pointers--inheritance gets screwed up.
We are talking about two different kinds of wrapping here.
Although it can be done to some degree, it would of course be incredibly difficult to create a class of smart pointers for each and every type of pointer use. Also, as you note, you would have to use those pointer types everywhere, which is another big strike against them. This kind of wrapping is not what I'm talking about.
I'm talking about doing responsible things like making the management of a given resource and the pointer to that resource a task of an object. I would say that this is not only something that can be done, but is something that should be done in almost every single circumstance. You get all the power but not nearly as many bugs.
Using string manipulation as a specific example, exactly what about std::string "severely limits language semantics"?
You can make strings reasonably safe, but strings are probably the easiest case. The hard part is data structures that refer to each other.
Of course, strings are probably the most common source of buffer overflow problems. This is why I brought up this specific example. There are a lorge number of generic classes in the STL that can manage resources well, like std::vector, std::list, and so on, none of which "limit language semantics".
But I do agree that here are times when it is tricky to do this sort of thing generically, and it is in these circumstances that you create a non-generic class to deal with it.
Sure there is [a way to achieve fault isolation in C++]. See man 2 fork, or CORBA
That's not fault isolation in C++, it's fault isolation in the operating system. That kind of approach has a lot of overhead. That's why programs like Netscape or Emacs are multi-megabyte executables composed of dozens of libraries, rather than a bunch of small, communicating, separate processes.
It also doesn't help a lot, since even running in separate processes, it's really easy for a process to corrupt (e.g., array index error) the data it then sends on to another process via CORBA; you still can't tell who did it in C++.
Whether you believe me or not that fault isolation through processes can't be used in many cases, the fact is that people don't use it, and that alone is indication enough that we need a different mechanism.
Are you asking how do we do an autopsy on the situation? That's easy... single process and one core dump. You can't be meaning that... you must be talking about run-time fault-tolerance and correction. When you need to do this sort of thing, then people most certainly break things down into modules seperated by process lines. A dataabase server or the TCP stack are both great examples of this.
No, good programming practices are what prevents bugs. IMHO there isn't much difference between the various type-safe languages in bug prevention, but there is a huge difference between the various programming practices and quality standards.
There isn't much difference among the various type safe languages in terms of bug prevention, but there is a huge difference between them and C/C++.
Just because type safety *can* be violated by wacky uses of objects doesn't mean that it isn't type safe. If people on a project are going to abuse the language, they're going to do it regardless of what language is going to be used.
[ Snipped talk about Ada and Modula-3 ]
Can you name any significantly large piece of software written in either of these two languages that I could examine?
The claim was that you can have other pointer models and not sacrifice any speed. I'm having a hard time imagining this, as "the C pointer model" mirrors the hardware very closely. I'm very, very willing to be corrected.
Well, first of all, you seem to agree as far as C is concerned since you advocate wrapping all those unsafe C interfaces into better C++ interfaces.
Yeah, pretty much so. Well-written C is attainable, of course, but the benefits of C++ are certainly worth switching.
C++ still uses the C pointer model and adds a similar reference model. And C++ still uses manual memory management for dynamic allocation. You cannot, in general, address those problems by creating safe abstractions. If you try, you end up severely limiting language semantics, and as soon as you face any outside library, you have to convert to raw pointers anyway.
Both the "C pointer model" and the manual memory management are easily wrappable. "Initialization is resource acquisition" is elegant and easy to stick to. You can also easily wrap the interfaces to the other libraries, as I said before. It can all be done very safely if you keep direct pointer operations to a minimum and thoroughly check them as you do. I feel that this extra bit of planning can be worth the power that is gained.
Using string manipulation as a specific example, exactly what about std::string "severely limits language semantics"?
And C++ still does not guarantee fault isolation among modules or any way of determining from the source code of a module whether that module is safe or not. That is, any piece of code you link with can cause arbitrary problems in any other piece of code, and you have no way of telling. Perhaps you think that's inevitable, but it is not. None of the other languages that I mentioned have that misfeature.
Arguing that one should not bother fixing those problems because there are lots of other ways in which people can make mistakes is wrong. The problems C/C++ creates for programmers are easily avoided, without performance penalty or other drawbacks. A day lost trying to chase some avoidable pointer bug in a C/C++ program is a day that could have been spent on testing and fixing some conceptual security bug.
No, good programming practices are what prevents bugs. IMHO there isn't much difference between the various type-safe languages in bug prevention, but there is a huge difference between the various programming practices and quality standards. I have talked with plenty of folks who claim that there's "no performance penalty or other drawbacks" to not having the power of C/C++'s low-level control, but I haven't seen anyone back that up with proof. I would really enjoy for someone, anyone, to prove otherwise.
The underlying problem is that C/C++/Objective-C do not have mechanisms to protect against these kinds of problems. In fact, it's impossible to write substantial programs in those languages that use only "safe" constructs.
I should note that the above use of the word "impossible" is misinform{ed,ing}, and bias{ed,ing}.
Management of buffers is a low-level detail that only needs to be taken care of once. Hiding details such as this is something that a good C++ programmer can do with elegance.
If you write a C++ application that uses intelligent string classes such as the STL's std::string, then it becomes very possible to write buffer-safe programs. In fact, it's kind of hard to use std::string in such a way that it does break. (Of course, you have to deal with the fact that all the syscalls use char[]'s rather than string objects, but most of those syscalls should also probably be wrapped in classes -- See the ACE lib).
As mentioned in other posts, it's often just as easy to create security problems (and other data-integrity-destroying bugs) in other languages.
If there is a "fundamental bug" that causes thesee problems, it's the low standard that we currently hold software to. Not even bringing in certain high-profile/buggy pieces of software into the picture, I can speak from personal experience on this one. Quality is a distant second to rapid deployment in many domains. Well-written and bug-free code is a subtle thing to enjoy, but one that I think will eventually come into greater popularity.
So if we could all, as engineers, begin to refuse to produce sloppy code in the face of deadlines and such, I think this type of situation will eventually fix itself.
Maybe you're misunderstanding what a 1-bit bitmap is, exactly...
It means to draw an image, you have a grid of lights that you can turn on or off. You don't get to change the color or intensity of the lights -- only whether they're on or off.
It doesn't matter what the color of these lights are when they're in the "on" and "off" position -- could be white, red, or anything else.
The "multicolored text" that you were talking about is just text that uses a color pair other than black and white.
So, as another fellow has said, the reason why you would want a more flexible bitmap is so you can "Anti-alias". The effect of this is that text is more legible in a smaller space.
I presume that the reason that X has always had only 1 bit for fonts is, as you pointed out, it takes longer. But X was also designed a very long time ago, and constraints are different now. Today, the data I/O to a graphics card is much faster, while monitor quality hasn't gone up that much. You can "fake" a higher resolution if you can have halftones and such.
I'm not going to go implement anything better... but it is valid to say that this is a shortcoming of XFree86 as it is. X4.0 might actually solve the problem, I haven't checked.
I wouldn't say "No" memory leaks. The whole point of garbage collection is to allow the programmer to create very complex data structures and not worry about it. Any monkey can match up a "new" and "delete" if they're within the same scope, or if the new is in the constructor and the delete is in the destructor. But, indeed, it does get much more difficult when you start trying have structures with multiple references to a value, and with references to the references, and so on. This is exactly the sort of thing that Perl's "garbage collecting" (reference-counting) doesn't help you with. Matter of fact, Perl's hurts more than it helps, in a lot of cases -- Take copy-on-write memory pages after having fork()'d. If you want to access a portion of memory in Perl, the access alone causes a write to that page, making the program have to copy the page. Et Cetera.
Katz, I don't have a thing against you, but comparing OSS to the New Jerusalem? That's not only insulting, it rings of a terribly limited imagination.
Do you really think that God, in all his infinite creativity, couldn't create a utopia any better than some smatterings of scripts and tangled C code?
I guarantee you I'll have better things to do than parse web logs by then.
Threads introduce non-deterministic interactions between different parts of a program. This can make adequate testing a pain.
Actually, this means XP testing (with its focus on unit testing) works very well when compared to the traditional "testing" model of code, run, visually-inspect. If you're getting a goofed up result from an operation, and the unit tests for each of its parts pass, you know you've got problem that's a result of the joining of the parts. In this case, the problem inside "joining of the parts" is most likely the concurrency.
If you have a terribly coupled model where the thread-spawning code is mixed in with the code that does real work, then I suppose I can see how it could get difficult to test. However, part of XP's design principles are to do things "Once and Only Once", so this type of code would be frowned upon even if it didn't make testing difficult.
- Dr. Foo Barson
If they can't find a way to make it work with threading, XP has some serious flaws.
Can you clarify that any? I must be missing something, because I cannot fathom how XP has any problems with threading.
GUI unit testing is a trick, but a common point of discussion on XP forums. It's doable in any of several dozen ways. From what I can tell, the only problem is that no one GUI testing practice has emerged as the best.
- Dr. Foo
However, pretty much every day, someone stupid would destroy her code under the guise of XP's constant state of refactoring.
Do you mean they broke its design, its style, or its functionality?
If you're referring to the design, then it is possible that your girlfriend is from the "old skool" of OOP -- overdesign everything and make everything conform to a particular arbitrary set of rules.
I don't mean that to sound insulting -- I used to be the same way. My coworkers changing my code was a constant annoyance because they would stomp all over my little flower garden. In retrospect, however, many of the changes that were made were good -- very simple, very clean. I was determined that good code should be uber general.
If you are referring to the coding styles and such -- that means that the team wasn't doing XP, because XP involves a coding standard. When I first saw that having a coding standard was one of the XP practices, I thought it odd and overly specific. But it is necessary to fit in with the XP practice of "collective ownership" of all code.
If they broke the functionality... well, then why wasn't there a unit test written? The avid unit testing of XP is one of the most visibly enjoyable aspects of the methodology. Traditionally, writing regression tests is a burden.
Beck and others have noticed how much better/faster/more confidently code can be developed if the unit tests are written before the units are implemented. You then implement until all the tests pass, and then you're done.
However, even if you're doing test-first programming like that, breakage will occasionally occur. But when things do break, you have to try to figure out (and write!) a test that could've ensured that the breakage wouldn't have happened. Eventually, (or so I've heard), you learn how to test well enough that you don't have this problem nearly ever.
Remember what ol' Kent Beck says about XP: "80% of the benefit comes from following the last 20% of the practices". In other words, if you are doing nine out of the twelve practices, you're probably only seeing 20% of the benefit. As soon as you plug in those last three is as soon as you'll see the biggest benefit of the methodology.
Of course, my diagnosis could've been completely wrong here -- I'm just taking some guesses.
- Dr. Foo Barson
(Quoting from the c2/wiki BeautyAintMyBusinessNoSir (which is a response to BeautyIsOurBusiness)):
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -- Buckminster Fuller
- Dr. Foo Barson
Anything like this for Win32? It would be nice!
Sure: http://www.mozillazine.org/build_comments/
I run Debian/Linux, and use that "build bar" to decide when to upgrade. It should be fine for Win32 users as well.
At the pace the Mozilla project is going, 0.7 is going to be obselete in a week, so keep the link handy.
- Dr. Foo Barson
Ahem.... (reading from the corrected version)
% cat tos.html | tr -sc a-zA-Z0-9\$ '\n' | \
translate any characters other than "a-z" (case-insensitive), "0-9", and "$" to newlines -- I.e., split everything up onto its own line.
sed -n -e 's/\(\$[0-9]+\)/<BR>&/p'
Then "grep" for dollar amounts, outputting them with HTML <br>'s so that they can easily be pasted into the /. form.
Fraud detector (patent applied for)
The joke is that there are a lot of dollar amounts mentioned in the TOS, which makes it sound a little fraudish. He wrote a shell pipeline to automatically extract dollar amounts from a document, which will give an indication of how much the author is interested in money.
FWIW, this could also be expressed as:
perl -ne 'print "\n<br>$1" while /(\$\d+)/g' tos.html
Which does the same thing but without the extra steps.
- Dr. Foo Barson, professional joke explainer/ruiner.
Anyhow, security was just an example. Suppose your first draft of the source code is just poorly formatted and doesn't have enough comments? Maybe you don't want everybody to get a bad first impression.
XP rule: all code is written according to a standard. So no, that's not a valid excuse. =)
I'm also a little lost as to the logic of your post. You start off talking about security, and then start talking about bugs. These are very different things.
Not usually. Look at any of the security boards... my estimate is that 80% of security holes are related to simple bugs, with the remaining 20% being architectural flaws.
If it is a simple bug, then my previous post applies -- why should it exist at all? If it is some deeper, "archetectural" level security issue, then it should certainly not be held secret with an insecure binary being released.
I can't imagine a person willfully advocating the release of an insecure binary without source for the purposes of fixing the insecurities in the background.
That's just messed up.
3. ... Suppose you write an initial version that is full of security holes, but that does demonstrate some key functionality. You might want to release a binary, then spend a month fixing the security, then open-source the project.
Oof. That's a very foolish thing to advise. Though I am not the first to rant against "Security through Obscurity", I'm going to have to speak against this one for sure.
Just so I get this straight... you're advocating giving a person a binary with security holes, and not informing them (either through source or English description) what those holes are? That's so absurd!
I am guessing that you are unaware of such tools as strace and ltrace, which would most likely leave the security hole in plain view, anyway.
But that's not even the half of it.
My real question is this: Why are the bugs there in the first place?
I am absolutely tired of buggy software. It should be (and as far as I'm concerned, is) a thing of the past. I am unable to understand why a person would write a line of buggy code, unless of course they don't understand how that can be done.
The idea is that you develop in micro-iterations... every time you want to add a feature, you write a test first, then you implement the interface until the tests all pass. When you are done, you have the guarantee that everything works, and that it will continue to work (because you never remove the test).
Other XP tenets that would very much help here are:
I have a good guess as to what your first rebuttal is going to be, "But what about experimental features?", as in features that are prototypical. In this case the practice of Spike Solutions becomes relevant.
None of this is just kooky theories. Well, they are that =)... but they're more -- people (including myself) are actually doing this and it is working. Since I've begun my adoption of the XP process, I've developed better code that is nearly 100% bug free at the end of each iteration, and I've developed it faster.
I realize that I linked more than I spoke, but I feel that the XP practices speak for themselves against the mindsets that I'm seeing in yours and other posts.
- Dr. Barson
12 sales out of 1308? Not bloody likely. The accepted statistic is 1 sale out of 1000 visitors and that statistic doesnt even take into account the 30% chargeback margin due to rampant credit card fraud.
Sorry, but it appears that you are spouting all these statistics based on your experience with porn sites.
Having worked for a company providing online stores for legitimate businesses (Ie, non-porn), I can say that it is very normal for there to be a >1% conversion rate. In addition, credit card fraud was an issue that seldom arose.
Matter of fact, the folks in charge of promoting the store always felt like %1 was a terrible number, and wanted to beat it.
I'd bet you can make a lot of errors by applying porn-site statistics to more general areas. (This just in!: Studies show 100% of web sites attempt to disable the back button via JavaScript.)
Apparently you have not heard of HTTP 0.9.
In the future, please reserve use of insults to for those who are less knowledgeable than yourself.
Yes, and all these things sadden me to some degree. I cut my teeth on Perl, and it's unfortunate for me to have to look back on the language of my youth as a "toy-language". I'll always use it as a day-to-day tool, but I must say that this project forever cured me of using any predominantly dynamically typed language for a lorge project.
I understand that Perl's purpose was never to be like C++ or Java, but I get the feeling that the perl interpreter is too busy trying to "please", accepting whatever I give it. Twistng Larry's quote about false laziness and such, I consider it "false postmodernism".
I certainly don't mean to say my $user = new UnprivilegedUser; $user->destroyTheWholeSystem(), and I would like some help from the interpreter to remind me when I try. Unless some sort of "use TypeCheck" pragma could be introduced, I see this whole thing as a death toll for Perl's use on a large/multi-developer project in exchange for a little niftiness in a few obscure situations.
Oy.
As the author of a 'big project' in Perl, I have to adamantly disagree. It's not Perl's fault. There are some languages that cuff you about the head and shoulders with a club and force you out of your 'random and unplanned' style, but not Perl. If you're an undisciplined programmer from the get go, Perl won't help you.
And as a member of a 'big project' in Perl (nearing 100k lines, ~10 full-time developers), I have to adamantly agree with the original poster.
You are right in saying that there are programming practices that other languages pretty much force you to use that Perl doesn't. This brings me to point #1:
Sometimes peole need "pushes" in the right direction. Not everyone will factor designs as elegantly as you would wish, and there are times when it's too tempting to get out a hack solution. Regardless of what theoretical arguments there are against this, I have seen it happen in practice over and over.
Perl gives a person a lot of control over primitives (strings, hashes, arrays). This is a great benifit in many uses, for example "perl -pi -e", being the most useful implementation of a "read/write grep" I can imagine. However, because it is so easy to pass primitives around, more sophisticated, abstracted types are seldom used. This can be overcome if every developer on the project is a very disciplined OO programmer, but even then Perl's object model is so much harder to use than, say, C++'s. Which brings me to point #2:
There are insurmountable problems in Perl's design that lead to too many things being checked at run-time.
For example, say I want to make a function that only accepts objects of a base type "AdminUser", how can I make sure that an object of type "UnprivilegedUser" doesn't get passed? Perl's answer: Run-time checks.
The simple case is when I wrote an obvious bug and the program will choke upon the first running. The less-simple case is when the code works under most statesduring debugging, but running it in a production environment causes some before-un-thought-of state to surface. Then, we have production code crashing. Or, worse, we have unprivileged users with admin rights in some cases. Suck.
In C++, I would've had a compile(or link)-time error raised explaining to me the situation. I highly question the value of being able to change classes at run-time anyway. Sure, folks like Damien Conway can make some tricky libraries, but beyond that reinventing the object model every time you write a class is a pain.
Please understand that this is *not* a strawman argument, as most of the hours in my day for the last six months have been spent debugging the above problem. It's also why I'm deeming this the last Perl project that I will ever work on.
- Ryan King
Am I missing something or did a "mod this up" post just get brought to +4?
We are talking about two different kinds of wrapping here.
Although it can be done to some degree, it would of course be incredibly difficult to create a class of smart pointers for each and every type of pointer use. Also, as you note, you would have to use those pointer types everywhere, which is another big strike against them. This kind of wrapping is not what I'm talking about.
I'm talking about doing responsible things like making the management of a given resource and the pointer to that resource a task of an object. I would say that this is not only something that can be done, but is something that should be done in almost every single circumstance. You get all the power but not nearly as many bugs.
Of course, strings are probably the most common source of buffer overflow problems. This is why I brought up this specific example. There are a lorge number of generic classes in the STL that can manage resources well, like std::vector, std::list, and so on, none of which "limit language semantics".
But I do agree that here are times when it is tricky to do this sort of thing generically, and it is in these circumstances that you create a non-generic class to deal with it.
Are you asking how do we do an autopsy on the situation? That's easy... single process and one core dump. You can't be meaning that... you must be talking about run-time fault-tolerance and correction. When you need to do this sort of thing, then people most certainly break things down into modules seperated by process lines. A dataabase server or the TCP stack are both great examples of this.
Just because type safety *can* be violated by wacky uses of objects doesn't mean that it isn't type safe. If people on a project are going to abuse the language, they're going to do it regardless of what language is going to be used.
[ Snipped talk about Ada and Modula-3 ]
Can you name any significantly large piece of software written in either of these two languages that I could examine?
The claim was that you can have other pointer models and not sacrifice any speed. I'm having a hard time imagining this, as "the C pointer model" mirrors the hardware very closely. I'm very, very willing to be corrected.
Well, first of all, you seem to agree as far as C is concerned since you advocate wrapping all those unsafe C interfaces into better C++ interfaces.
Yeah, pretty much so. Well-written C is attainable, of course, but the benefits of C++ are certainly worth switching.
C++ still uses the C pointer model and adds a similar reference model. And C++ still uses manual memory management for dynamic allocation. You cannot, in general, address those problems by creating safe abstractions. If you try, you end up severely limiting language semantics, and as soon as you face any outside library, you have to convert to raw pointers anyway.
Both the "C pointer model" and the manual memory management are easily wrappable. "Initialization is resource acquisition" is elegant and easy to stick to. You can also easily wrap the interfaces to the other libraries, as I said before. It can all be done very safely if you keep direct pointer operations to a minimum and thoroughly check them as you do. I feel that this extra bit of planning can be worth the power that is gained.
Using string manipulation as a specific example, exactly what about std::string "severely limits language semantics"?
And C++ still does not guarantee fault isolation among modules or any way of determining from the source code of a module whether that module is safe or not. That is, any piece of code you link with can cause arbitrary problems in any other piece of code, and you have no way of telling. Perhaps you think that's inevitable, but it is not. None of the other languages that I mentioned have that misfeature.
Sure there is. See man 2 fork, or CORBA
Arguing that one should not bother fixing those problems because there are lots of other ways in which people can make mistakes is wrong. The problems C/C++ creates for programmers are easily avoided, without performance penalty or other drawbacks. A day lost trying to chase some avoidable pointer bug in a C/C++ program is a day that could have been spent on testing and fixing some conceptual security bug.
No, good programming practices are what prevents bugs. IMHO there isn't much difference between the various type-safe languages in bug prevention, but there is a huge difference between the various programming practices and quality standards. I have talked with plenty of folks who claim that there's "no performance penalty or other drawbacks" to not having the power of C/C++'s low-level control, but I haven't seen anyone back that up with proof. I would really enjoy for someone, anyone, to prove otherwise.
The underlying problem is that C/C++/Objective-C do not have mechanisms to protect against these kinds of problems. In fact, it's impossible to write substantial programs in those languages that use only "safe" constructs.
I should note that the above use of the word "impossible" is misinform{ed,ing}, and bias{ed,ing}.
Management of buffers is a low-level detail that only needs to be taken care of once. Hiding details such as this is something that a good C++ programmer can do with elegance.
If you write a C++ application that uses intelligent string classes such as the STL's std::string, then it becomes very possible to write buffer-safe programs. In fact, it's kind of hard to use std::string in such a way that it does break. (Of course, you have to deal with the fact that all the syscalls use char[]'s rather than string objects, but most of those syscalls should also probably be wrapped in classes -- See the ACE lib).
As mentioned in other posts, it's often just as easy to create security problems (and other data-integrity-destroying bugs) in other languages.
If there is a "fundamental bug" that causes thesee problems, it's the low standard that we currently hold software to. Not even bringing in certain high-profile/buggy pieces of software into the picture, I can speak from personal experience on this one. Quality is a distant second to rapid deployment in many domains. Well-written and bug-free code is a subtle thing to enjoy, but one that I think will eventually come into greater popularity.
So if we could all, as engineers, begin to refuse to produce sloppy code in the face of deadlines and such, I think this type of situation will eventually fix itself.
Just my thirty pieces of silver's worth.
Maybe you're misunderstanding what a 1-bit bitmap is, exactly...
It means to draw an image, you have a grid of lights that you can turn on or off. You don't get to change the color or intensity of the lights -- only whether they're on or off.
It doesn't matter what the color of these lights are when they're in the "on" and "off" position -- could be white, red, or anything else.
The "multicolored text" that you were talking about is just text that uses a color pair other than black and white.
So, as another fellow has said, the reason why you would want a more flexible bitmap is so you can "Anti-alias". The effect of this is that text is more legible in a smaller space.
I presume that the reason that X has always had only 1 bit for fonts is, as you pointed out, it takes longer. But X was also designed a very long time ago, and constraints are different now. Today, the data I/O to a graphics card is much faster, while monitor quality hasn't gone up that much. You can "fake" a higher resolution if you can have halftones and such.
I'm not going to go implement anything better... but it is valid to say that this is a shortcoming of XFree86 as it is. X4.0 might actually solve the problem, I haven't checked.
Hoot!
Yes, but "at the display level", you don't use a 1-bit bitmap.
The problem isn't that X does fonting in bitmaps, but that it does them in single-bit ones.
I wouldn't say "No" memory leaks. The whole point of garbage collection is to allow the programmer to create very complex data structures and not worry about it. Any monkey can match up a "new" and "delete" if they're within the same scope, or if the new is in the constructor and the delete is in the destructor. But, indeed, it does get much more difficult when you start trying have structures with multiple references to a value, and with references to the references, and so on. This is exactly the sort of thing that Perl's "garbage collecting" (reference-counting) doesn't help you with. Matter of fact, Perl's hurts more than it helps, in a lot of cases -- Take copy-on-write memory pages after having fork()'d. If you want to access a portion of memory in Perl, the access alone causes a write to that page, making the program have to copy the page. Et Cetera.