In US, anything some group of rich assholes wants to do with information or art is either "copyright" (when a cult does not want its beliefs and practices discussed in public, or public domain work becomes inaccessible after some company makes an animated movie based on it and claims its ownership) or "freedom of speech" (a cover for fraud, blackmail, libel, conspiracy, propaganda and harassment).
Why you'd want bars at top AND bottom of the screen is a mystery to me
Top: Actions and status. Bottom: Window and virtual desktop selection and previews.
There is no way both can fit into the same bar -- there is just no enough space. This is NOT ABOUT THE DEFAULT CONFIGURATION WITH THE EMPTY TOP BAR, that Ubuntu so carefully imitated in their sad mockery of GNOME2, it's about what desktop looks like after the user adds everything he needs to the top bar and still wants to see the list of windows on all his desktops, and be able to hover for window previews, on the bottom.
There is also a matter of user-selectable window manager. I need "Previous virtual desktop"/"Next virtual desktop" bound to the mouse buttons 8 and 9, Expo to left bottom corner and Scale to upper left corner. This is very important for me because I have three monitors connected to three computers running Synergy, so screen edges must be consistent. Compiz is currently the only window manager that allows such customization, however GNOME3 does not support window managers other than its own built-in one, XFCE and LXDE break horribly with Compiz.
I have to use _KDE_ on Ubuntu to get this on 11.10.
This is absolutely horrible, and whoever came up with this thing, should resign from GNOME and go work for Google on Android-without-Java, because this is where it belongs.
P.S. I disagree about optimization -- most-used arguments and local variables are usually placed into registers, so functions with a small number of either will be optimized in a similar manner. Flags are in registers, so their cost is the lowest (no dereference), dereferences of ptr1 and ptr2 happen close in code with no changes to the pointers, so compiler combines those dereferences (and the logic of both if/return).
The tests with gcc -O2 on Intel show that compiler indeed does so, and achieves similar performance -- your version is significantly smaller but slightly slower. Surprisingly, both -Os and -O3 produce worse results than -O2, so apparently performance of this function (at least outside of large programs, inlining, etc.) is mostly affected by memory accesses.
This is exactly the kind of problem I am talking about. not_equal_concatenated("abc","","abc",NULL) will return 1, what would be an inconsistent handling of NULL -- equivalent of empty string in the "head", not an equivalent of it in the "tail". My version of this function always treats NULL as an equivalent of an empty string, so unless this is the intention (if NULLs are specifically excluded from the supported arguments what just as well may be the case in some applications), it's not a valid replacement of the first or third solutions that specifically handle NULLs. Unless tests specifically cover all combinations that include both NULLs and empty strings, they would not find any difference.
Keeping the same notation (omitting explicit comparison with NULL that I used entirely for readability), it can be fixed: int not_equal_concatenated(const char *a, const char *a1, const char *b, const char *b1) {
do
{
if (!a || *a == '\0')
{
a = a1;
a1 = NULL;
if(a && *a == '\0')
a = NULL;
}
if (!b || *b == '\0')
{
b = b1;
b1 = NULL;
if(b && *b == '\0')
b = NULL;
}
if (!a && !b) return 0;
if (!a || !b) return 1;
} while( *a++ == *b++);
return 1; }
(I was not too thrilled with the use of comma to avoid braces in the first place, but now it would be pointless. Just please, no a=a?(*a?a:NULL):a; -- we all can write like that but shouldn't. On the other hand, const is very much justified if it was a real-life application).
It now works, but please look at the nature of the fix. It specifically covers the particular situation that causes a known scenario of misbehavior. In this case, it is sufficient because it restores the NULL/end-of-string equivalence that the function relies on, however a programmer who discovered such a corner case in a test, may be tempted to fix a newly found breakage scenario without knowing if it fixes one scenario or all possible scenarios.
I'm not sure I understand what you mean here, How do you prove that it can not break?
Let's try to make a somewhat practical solution to a really stupid and pointless task:
Implement a C fuction int not_equal_concatenated() that takes four C strings as an input and tests the equality of two strings that are produced by concatenation of the first and second pairs of arguments, returning 0 for equal, 1 for not equal, -1 for error if it has any error conditions. For example, arguments "abcd","efgh","abc","defgh" would return 0 (equal) and "abcd","efgh","abcd","efghi" return 1 (not equal). As opposed to strcmp() it should only test equality -- negative return values are for errors. Solution may have limitations that cause errors to be returned.
The task is artificial, so the solution is guaranteed to look very ugly, but this is not the point.
First solution: char *alloc_concatenate(char *s1, char *s2) {
char *result,c='\0';
if(s1==NULL)
s1=&c;
if(s2==NULL)
s2=&c;
result=malloc(strlen(s1)+strlen(s2)+1);
if(result==NULL)
return NULL;
strcpy(result,s1);
strcat(result,s2);
return result; }
int not_equal_concatenated(char *s1head,char *s1tail,char *s2head,char *s2tail) {
int result;
char *s1,*s2;
Let's see what assumptions would have to be made by a programmer who believes, this code will always work properly.
Both make one fundamental assumption that each argument is a valid pointer to a zero-terminated string (or NULL in the first example, though the second will work with NULL on some systems). It can be shown though that even if that requirement is not met, the program will crash without producing a buffer overflow or other exploitable problem beyond the fact of the crash itself -- it will eventually run out of accessible memory but will not try to alter it (at least as long as we are dealing with userspace on a system with protected memory -- some projects do not). However it would be fair to say that giving an invalid non-NULL pointer to string is never acceptable in the first place.
First solution also makes an assumption that it's safe and acceptable to allocate the amount of memory equal to the total size of the strings plus terminating zero. If allocation fails, and system reports the error, the function will return -1, however on most systems it would just cause the process to be killed. It treats NULL an an equivalent of an empty string, this is not specified in the problem but perfectly reasonable if documented.
It also sacrifices performance for simplicity -- it would be better to take the length of the fir
And they all require Javascript as the only supported scripting language (one you use to actually DO something on the client), all the ugliness carefully preserved.
I recognize that this is a significant progress compared to previous HTML/CSS/Javascript combinations. However that's only because previous HTML standards and Javascript are so awful. It may use little of Javascript when UI is tolerant to high-latency requests to the server, but there is no way to escape that language completely.
I don't think, I can be of much help with that beyond the obvious -- unless you are lucky with Coreboot support on your hardware, BIOS development requires licensing some very proprietary, ugly and sanity-destroying code. I believe, Coreboot already can run GRUB2 from the same flash as itself, so that would be a healthier direction if it is available on your hardware platform.
The modified utilities used in that particular project (grub and flashrom) are at http://www.meyersound.com/opensource/code/ , however they are of little use without the change in BIOS -- it copies the full bootloader (second stage) from a section of flash instead of reading the boot/MBR sector from whatever boot device it recognized. Boot device is still accessible from BIOS (because it performed all steps necessary to make it a boot device, just didn't try to read it), so GRUB finds itself in a familiar environment and can read partitions with any supported filesystems, completely ignoring MBR and boot sectors if configured to do so.
That particular project used a small BIOS chip, so it was not practical to store anything other than BIOS and GRUB there, however someone else may end up modifying GRUB to load things from there instead of looking at the boot device (or be called if there is no boot device like ROM BASIC on the original PC). It would be also nice to make GRUB2 work with modules from flash.
It's also used in quite a few embedded systems running low-end x86 chips. The advantage of something like DOS in this respect is that it's almost like not having an OS, but it still gives you a basic filesystem and program launcher, then gets out of your way.
Actually that would be the original GRUB (or GRUB2 if you like having a requirement for boot media that contains modules -- I don't because my embedded system that uses it, boots from a section in the same flash chip as BIOS).
At this point I think it's time for me to upgrade from FreeDOS to ReactOS.
FreeDOS has legitimate uses -- I have found it on manufacturers' BIOS updater images. I, of course, do my updates under Linux with flashrom utility, but I have some taste and sanity, things that most people lose after being exposed to BIOS source code.
So what methods do you use to minimize bugs in your code?
Write it as if it is going to be tomorrow placed into a space probe and launched out of the Solar System. In other words, write it in a way so it will be always possible to prove that it can not break under any conditions that it may be subjected to. Even if you will mess up, you will do it rarely, and will remember how embarrassing it was last time you did, and where your reasoning was faulty. When mistakes are counted by thousands, programmer does not feel that they are something undesirable even if he rationally understands it. This still does not help if the rest of the system breaks horribly in unspecified and unexpected manner, but produces reliable software otherwise.
It is perfectly in line with the goals of producing the result with maximum reuse and minimal amount of new code (less code means less opportunities for bugs and more time for thinking about it), and being aware of all interfaces being used (document things clearly and keep them in your mind when you use them -- if you need IDE or, $deity forbids, Hungarian notation to remind yourself of the types in your own internal interface, resign immediately because you no longer can use it in a safe manner).
Surprisingly, all modern IDEs with their multitude of little list windows around the centered tabbed source editor window, break the screen layout I have found very helpful for keeping myself aware of references within a project -- two windows with source code side by side, so it's always possible to get a piece of code and another piece of code it refers to (implementation, prototype/declaration or even documentation), simultaneously within your field of view. It's hardly a panacea, but it creates a situation that no physical or mental effort is necessary to make certain that you know what you are dealing with. With a single tabbed window, casual lookup comes at a tremendous cost -- you sort through hundreds of tabs, lose your original file, then return to it trying to remember what you have seen. Actual thinking of what it means for the code you are writing, becomes difficult. Vertically split vim or emacs impose no such penalty -- main window is on the left, so switch to the window on the right, select a file (or go to another section of the same file), keep your editing intact and visible in the original left window.
How about never ever passing any input to SQL interpreter, use prepared statements based on nothing but constants, and always store data in bind variables? Even MySQL supports that.
Of course, it's not PHP's fault that mysql_real_escape_string() is a part of MySQL API, however it would be nice if a language widely used for database-backed web applications did not support the most idiotic way of passing data to the INSERT statement.
Here is your problem. Javascript is an awful language, it just by the whim of Netscape it is the only one available in a browser. This does not mean, Javascript is good, it means that Netscape fucked up, and no one was around to fix the problem because everyone was busy fending off Microsoft and Adobe, who tried to "standardize" everyone on things that make Javascript look good.
A good solution would be to use Java or C++ with Qt, and distribute the application with sources (and everyone who opens his mouth about revealing the source code is welcome to shut up because Javascript is always distributed in source anyway). This may be an overkill for something as simple as a widget for displaying lists/icons/graphs..., but for a complex application Javascript is still a bad language.
Same applies to writing "for consumer PC" and Win32/.NET/other horrible things from my "favorite" company.
You're just retarded and wrong. Vendors DO foot the bull for refunds of unused Windows licenses.
The whole point of Windows refund is to not fund Microsoft's world conquest.
Every once in a while you get a story about some nerd who makes a video of themselves saying NO to the Windows EULA, restarting the computer, and then wiping the drive and installing Linux, just so they can get $30 back from the OEM after making a stink about it.
Oh, I see. More Microsoft astroturfers.
Listen, asshole. I don't care too much about my money. Whatever money I have, I use to buy things I like, and I have enough for that. I care about Microsoft's money. To be precise, about Microsoft not getting any from me. If you don't understand this, go kill some old lady or something -- it's not like you have any kind of ethic.
I find the nomenclature of "patterns", and especially their attribution to OOP misleading. It creates an impression that good programming is based on know a predefined set of "tricks" instead of ability to create those solutions on the fly based on a problem being solved.
Well designed. Because of this abstraction, you can take programs that were written for Linux, and run them on a completely different kernel, such as BSD. OOP at its finest.
It's not OOP at all. OOP interface has to operate on objects, and to do so it has to propagate their identity and sometimes their type. With Unix syscalls interface, not only you usually don't know, or care, what kind of object you are operating on (what allows to generalize things like IPC and remote access over the network), you don't have the object's identity (for example, file descriptors could be be duplicated, and multiple processes may have the same kernel object seen as completely unelated file descriptors).
On the other hand, when you do know a kind of object you are dealing with (say, device file) you may have to use the same syscall (say, write() ) to perform only vaguely related functionality -- it's grouped under write() because it can be described as "send some data", and access to such operation is equivalent to ability to alter something. It would be a very poor OO design to have write() on a file, write() on a block device that contains a filesystem and write() on a pipe to be the same operation, and yet this is why I can use two pieces of software that were never designed to do anything related to software installation and deployment, ssh and dd, to remotely re-image drives. The reason for it, in OO new methods are "cheap" -- adding a new one is supposed to be easy, and interfaces have to accommodate it. In Unix, new syscalls are "expensive" -- adding a new syscall is a major event in the operating system's history. This keeps a limited number of entry points, allows to impose a single security model, and allows to re-use software for multiple unrelated purposes -- say, the same dd re-images drives and configures signal generators. Yes, "messages" would cover this, but messages are not an object-oriented feature, a specific kind of message, an event that triggers a call to a method (that can be polymorphic and affects specific encapsulated unit of data that is the message's explicit destination), is object-oriented.
Seriously, look at the list of OOP terms on wikipedia [wikipedia.org]. I'm not sure you understand the level to which OOP has expanded its meaning.
No. People misuse "OOP" as a term that they apply to everything they know, because they learned something in a context of object-oriented programming. This is a result of their limited knowledge, it does not affect the definition of OOP -- a software development principle that involves encapsulation, inheritance and polymorphism.
Things like dynamically-typed-language, namespace, recursion, and typecasting show up on the list. What things are not considered OOP?
None of them are OOP. Those are things that present in OO and non-OO programming. C++ templates are not an object-oriented feature, either (by their nature they are macros that operate on types), they just happen to be a language feature that is applied only in the context of polymorphism, what makes the results of their application object-oriented. You can add templates to assembly, Forttran, Basic, without changing the nature of those languages. Yeah, I can see it -- COMMON blocks from FORTRAN IV with templates. It would work. I would not be surprised if someone wrote a preprocessor that does something like that.
"non-OOP programs may be one "long" list of statements (or commands). With designs of this sort, it is common for some of the program's data to be 'global....means that bugs can have wide-reaching effects."
This is not about monopoly abuse. I mean if Microsoft is demanding that vendors do not offer refunds to consumers as the Vendor has written into their contracts then maybe that is monopoly abuse. Or if microsoft is threatening sactions against those vendors that do honour the refunds... then yes it is monopoly abuse.
Are you INSANE??? Of course, vendors don't have to foot the bill for refunds. Microsoft produces Windows, so refunds have to happen at Microsoft expense, just like with any other product. Microsoft does not allow vendors or consumers to return its product for refund, and does not allow vendors to re-stock returned Windows licenses for use on other products (what any other vendor of any other product would do) so it's entirely Microsoft's doing.
1. There are many other Ubuntu derivatives that as far as I know never had direct support from Canonical. Kubuntu is not going to disappear just because it is now at the same level as Xubuntu, Edubuntu, Lubuntu and other projects. 2. Kubuntu itself is an installer, KDE customizations and a set of dependencies. As long as Canonical (or anyone) supports KDE packages, it is at the same level of "legitimacy" as KDE support in Debian. 3. Oh, it's anti-Linux propaganda worker Brian Proffitt again. Figures. 4. Canonical made a really bad move with Unity that was followed with a worse move by Gnome. This leaves KDE as the best desktop environment currently supported by developers. 5. Kubuntu remains the only Ubuntu-derived distribution that supports sane window management, and can be reasonably customized (with Compiz instead of kwin). It's also the best desktop Linux distribution that currently exists.
In US, anything some group of rich assholes wants to do with information or art is either "copyright" (when a cult does not want its beliefs and practices discussed in public, or public domain work becomes inaccessible after some company makes an animated movie based on it and claims its ownership) or "freedom of speech" (a cover for fraud, blackmail, libel, conspiracy, propaganda and harassment).
Why you'd want bars at top AND bottom of the screen is a mystery to me
Top: Actions and status.
Bottom: Window and virtual desktop selection and previews.
There is no way both can fit into the same bar -- there is just no enough space. This is NOT ABOUT THE DEFAULT CONFIGURATION WITH THE EMPTY TOP BAR, that Ubuntu so carefully imitated in their sad mockery of GNOME2, it's about what desktop looks like after the user adds everything he needs to the top bar and still wants to see the list of windows on all his desktops, and be able to hover for window previews, on the bottom.
There is also a matter of user-selectable window manager. I need "Previous virtual desktop"/"Next virtual desktop" bound to the mouse buttons 8 and 9, Expo to left bottom corner and Scale to upper left corner. This is very important for me because I have three monitors connected to three computers running Synergy, so screen edges must be consistent. Compiz is currently the only window manager that allows such customization, however GNOME3 does not support window managers other than its own built-in one, XFCE and LXDE break horribly with Compiz.
I have to use _KDE_ on Ubuntu to get this on 11.10.
This is absolutely horrible, and whoever came up with this thing, should resign from GNOME and go work for Google on Android-without-Java, because this is where it belongs.
mankind's inalienable rights, the ones the US founding fathers identified
This is precisely the problem that the rest of the world has with US and Americans.
"It's AWWWRIGHT!!!" is an opinion.
P.S. I disagree about optimization -- most-used arguments and local variables are usually placed into registers, so functions with a small number of either will be optimized in a similar manner. Flags are in registers, so their cost is the lowest (no dereference), dereferences of ptr1 and ptr2 happen close in code with no changes to the pointers, so compiler combines those dereferences (and the logic of both if/return).
The tests with gcc -O2 on Intel show that compiler indeed does so, and achieves similar performance -- your version is significantly smaller but slightly slower. Surprisingly, both -Os and -O3 produce worse results than -O2, so apparently performance of this function (at least outside of large programs, inlining, etc.) is mostly affected by memory accesses.
This is exactly the kind of problem I am talking about. not_equal_concatenated("abc","","abc",NULL) will return 1, what would be an inconsistent handling of NULL -- equivalent of empty string in the "head", not an equivalent of it in the "tail". My version of this function always treats NULL as an equivalent of an empty string, so unless this is the intention (if NULLs are specifically excluded from the supported arguments what just as well may be the case in some applications), it's not a valid replacement of the first or third solutions that specifically handle NULLs. Unless tests specifically cover all combinations that include both NULLs and empty strings, they would not find any difference.
Keeping the same notation (omitting explicit comparison with NULL that I used entirely for readability), it can be fixed:
int not_equal_concatenated(const char *a, const char *a1, const char *b, const char *b1)
{
do
{
if (!a || *a == '\0')
{
a = a1;
a1 = NULL;
if(a && *a == '\0')
a = NULL;
}
if (!b || *b == '\0')
{
b = b1;
b1 = NULL;
if(b && *b == '\0')
b = NULL;
}
if (!a && !b) return 0;
if (!a || !b) return 1;
} while( *a++ == *b++);
return 1;
}
(I was not too thrilled with the use of comma to avoid braces in the first place, but now it would be pointless. Just please, no a=a?(*a?a:NULL):a; -- we all can write like that but shouldn't. On the other hand, const is very much justified if it was a real-life application).
It now works, but please look at the nature of the fix. It specifically covers the particular situation that causes a known scenario of misbehavior. In this case, it is sufficient because it restores the NULL/end-of-string equivalence that the function relies on, however a programmer who discovered such a corner case in a test, may be tempted to fix a newly found breakage scenario without knowing if it fixes one scenario or all possible scenarios.
I'm not sure I understand what you mean here, How do you prove that it can not break?
Let's try to make a somewhat practical solution to a really stupid and pointless task:
Implement a C fuction int not_equal_concatenated() that takes four C strings as an input and tests the equality of two strings that are produced by concatenation of the first and second pairs of arguments, returning 0 for equal, 1 for not equal, -1 for error if it has any error conditions. For example, arguments "abcd","efgh","abc","defgh" would return 0 (equal) and "abcd","efgh","abcd","efghi" return 1 (not equal). As opposed to strcmp() it should only test equality -- negative return values are for errors. Solution may have limitations that cause errors to be returned.
The task is artificial, so the solution is guaranteed to look very ugly, but this is not the point.
First solution:
char *alloc_concatenate(char *s1, char *s2)
{
char *result,c='\0';
if(s1==NULL)
s1=&c;
if(s2==NULL)
s2=&c;
result=malloc(strlen(s1)+strlen(s2)+1);
if(result==NULL)
return NULL;
strcpy(result,s1);
strcat(result,s2);
return result;
}
int not_equal_concatenated(char *s1head,char *s1tail,char *s2head,char *s2tail)
{
int result;
char *s1,*s2;
s1=alloc_concatenate(s1head,s1tail);
s2=alloc_concatenate(s2head,s2tail);
if((s1!=NULL)&&(s2!=NULL))
result=strcmp(s1,s2)!=0;
else
result=-1;
if(s1!=NULL)
free(s1);
if(s2!=NULL)
free(s2);
return result;
}
Second solution:
#define BUFSIZE 1024
int not_equal_concatenated(char *s1head,char *s1tail,char *s2head,char *s2tail)
{
char s1[BUFSIZE],s2[BUFSIZE];
if(snprintf(s1,sizeof(s1),"%s%s",s1head,s1tail)>=sizeof(s1))
return -1;
if(snprintf(s2,sizeof(s2),"%s%s",s2head,s2tail)>=sizeof(s2))
return -1;
return strcmp(s1,s2)!=0;
}
Let's see what assumptions would have to be made by a programmer who believes, this code will always work properly.
Both make one fundamental assumption that each argument is a valid pointer to a zero-terminated string (or NULL in the first example, though the second will work with NULL on some systems). It can be shown though that even if that requirement is not met, the program will crash without producing a buffer overflow or other exploitable problem beyond the fact of the crash itself -- it will eventually run out of accessible memory but will not try to alter it (at least as long as we are dealing with userspace on a system with protected memory -- some projects do not). However it would be fair to say that giving an invalid non-NULL pointer to string is never acceptable in the first place.
First solution also makes an assumption that it's safe and acceptable to allocate the amount of memory equal to the total size of the strings plus terminating zero. If allocation fails, and system reports the error, the function will return -1, however on most systems it would just cause the process to be killed. It treats NULL an an equivalent of an empty string, this is not specified in the problem but perfectly reasonable if documented.
It also sacrifices performance for simplicity -- it would be better to take the length of the fir
And they all require Javascript as the only supported scripting language (one you use to actually DO something on the client), all the ugliness carefully preserved.
I recognize that this is a significant progress compared to previous HTML/CSS/Javascript combinations. However that's only because previous HTML standards and Javascript are so awful. It may use little of Javascript when UI is tolerant to high-latency requests to the server, but there is no way to escape that language completely.
I don't think, I can be of much help with that beyond the obvious -- unless you are lucky with Coreboot support on your hardware, BIOS development requires licensing some very proprietary, ugly and sanity-destroying code. I believe, Coreboot already can run GRUB2 from the same flash as itself, so that would be a healthier direction if it is available on your hardware platform.
The modified utilities used in that particular project (grub and flashrom) are at http://www.meyersound.com/opensource/code/ , however they are of little use without the change in BIOS -- it copies the full bootloader (second stage) from a section of flash instead of reading the boot/MBR sector from whatever boot device it recognized. Boot device is still accessible from BIOS (because it performed all steps necessary to make it a boot device, just didn't try to read it), so GRUB finds itself in a familiar environment and can read partitions with any supported filesystems, completely ignoring MBR and boot sectors if configured to do so.
That particular project used a small BIOS chip, so it was not practical to store anything other than BIOS and GRUB there, however someone else may end up modifying GRUB to load things from there instead of looking at the boot device (or be called if there is no boot device like ROM BASIC on the original PC). It would be also nice to make GRUB2 work with modules from flash.
Probably non-portable, too.
All servers support that. Not all developers know though.
It's also used in quite a few embedded systems running low-end x86 chips. The advantage of something like DOS in this respect is that it's almost like not having an OS, but it still gives you a basic filesystem and program launcher, then gets out of your way.
Actually that would be the original GRUB (or GRUB2 if you like having a requirement for boot media that contains modules -- I don't because my embedded system that uses it, boots from a section in the same flash chip as BIOS).
daily use
To do WHAT?
At this point I think it's time for me to upgrade from FreeDOS to ReactOS.
FreeDOS has legitimate uses -- I have found it on manufacturers' BIOS updater images.
I, of course, do my updates under Linux with flashrom utility, but I have some taste and sanity, things that most people lose after being exposed to BIOS source code.
So what methods do you use to minimize bugs in your code?
Write it as if it is going to be tomorrow placed into a space probe and launched out of the Solar System. In other words, write it in a way so it will be always possible to prove that it can not break under any conditions that it may be subjected to. Even if you will mess up, you will do it rarely, and will remember how embarrassing it was last time you did, and where your reasoning was faulty. When mistakes are counted by thousands, programmer does not feel that they are something undesirable even if he rationally understands it. This still does not help if the rest of the system breaks horribly in unspecified and unexpected manner, but produces reliable software otherwise.
It is perfectly in line with the goals of producing the result with maximum reuse and minimal amount of new code (less code means less opportunities for bugs and more time for thinking about it), and being aware of all interfaces being used (document things clearly and keep them in your mind when you use them -- if you need IDE or, $deity forbids, Hungarian notation to remind yourself of the types in your own internal interface, resign immediately because you no longer can use it in a safe manner).
Surprisingly, all modern IDEs with their multitude of little list windows around the centered tabbed source editor window, break the screen layout I have found very helpful for keeping myself aware of references within a project -- two windows with source code side by side, so it's always possible to get a piece of code and another piece of code it refers to (implementation, prototype/declaration or even documentation), simultaneously within your field of view. It's hardly a panacea, but it creates a situation that no physical or mental effort is necessary to make certain that you know what you are dealing with. With a single tabbed window, casual lookup comes at a tremendous cost -- you sort through hundreds of tabs, lose your original file, then return to it trying to remember what you have seen. Actual thinking of what it means for the code you are writing, becomes difficult. Vertically split vim or emacs impose no such penalty -- main window is on the left, so switch to the window on the right, select a file (or go to another section of the same file), keep your editing intact and visible in the original left window.
But that's what works for me.
How about never ever passing any input to SQL interpreter, use prepared statements based on nothing but constants, and always store data in bind variables? Even MySQL supports that.
Of course, it's not PHP's fault that mysql_real_escape_string() is a part of MySQL API, however it would be nice if a language widely used for database-backed web applications did not support the most idiotic way of passing data to the INSERT statement.
web
Here is your problem. Javascript is an awful language, it just by the whim of Netscape it is the only one available in a browser. This does not mean, Javascript is good, it means that Netscape fucked up, and no one was around to fix the problem because everyone was busy fending off Microsoft and Adobe, who tried to "standardize" everyone on things that make Javascript look good.
A good solution would be to use Java or C++ with Qt, and distribute the application with sources (and everyone who opens his mouth about revealing the source code is welcome to shut up because Javascript is always distributed in source anyway). This may be an overkill for something as simple as a widget for displaying lists/icons/graphs..., but for a complex application Javascript is still a bad language.
Same applies to writing "for consumer PC" and Win32/.NET/other horrible things from my "favorite" company.
You're just retarded and wrong.
Vendors DO foot the bull for refunds of unused Windows licenses.
The whole point of Windows refund is to not fund Microsoft's world conquest.
Every once in a while you get a story about some nerd who makes a video of themselves saying NO to the Windows EULA, restarting the computer, and then wiping the drive and installing Linux, just so they can get $30 back from the OEM after making a stink about it.
Oh, I see. More Microsoft astroturfers.
Listen, asshole. I don't care too much about my money. Whatever money I have, I use to buy things I like, and I have enough for that. I care about Microsoft's money. To be precise, about Microsoft not getting any from me. If you don't understand this, go kill some old lady or something -- it's not like you have any kind of ethic.
Replace xfwm with metacity, then.
I would rather run tvtwm.
Oh, sure I can run it. It just doesn't work when I try to do anything with it.
Ah, it's an abstraction pattern.
I find the nomenclature of "patterns", and especially their attribution to OOP misleading. It creates an impression that good programming is based on know a predefined set of "tricks" instead of ability to create those solutions on the fly based on a problem being solved.
Well designed. Because of this abstraction, you can take programs that were written for Linux, and run them on a completely different kernel, such as BSD. OOP at its finest.
It's not OOP at all. OOP interface has to operate on objects, and to do so it has to propagate their identity and sometimes their type. With Unix syscalls interface, not only you usually don't know, or care, what kind of object you are operating on (what allows to generalize things like IPC and remote access over the network), you don't have the object's identity (for example, file descriptors could be be duplicated, and multiple processes may have the same kernel object seen as completely unelated file descriptors).
On the other hand, when you do know a kind of object you are dealing with (say, device file) you may have to use the same syscall (say, write() ) to perform only vaguely related functionality -- it's grouped under write() because it can be described as "send some data", and access to such operation is equivalent to ability to alter something. It would be a very poor OO design to have write() on a file, write() on a block device that contains a filesystem and write() on a pipe to be the same operation, and yet this is why I can use two pieces of software that were never designed to do anything related to software installation and deployment, ssh and dd, to remotely re-image drives. The reason for it, in OO new methods are "cheap" -- adding a new one is supposed to be easy, and interfaces have to accommodate it. In Unix, new syscalls are "expensive" -- adding a new syscall is a major event in the operating system's history. This keeps a limited number of entry points, allows to impose a single security model, and allows to re-use software for multiple unrelated purposes -- say, the same dd re-images drives and configures signal generators. Yes, "messages" would cover this, but messages are not an object-oriented feature, a specific kind of message, an event that triggers a call to a method (that can be polymorphic and affects specific encapsulated unit of data that is the message's explicit destination), is object-oriented.
Seriously, look at the list of OOP terms on wikipedia [wikipedia.org]. I'm not sure you understand the level to which OOP has expanded its meaning.
No. People misuse "OOP" as a term that they apply to everything they know, because they learned something in a context of object-oriented programming. This is a result of their limited knowledge, it does not affect the definition of OOP -- a software development principle that involves encapsulation, inheritance and polymorphism.
Things like dynamically-typed-language, namespace, recursion, and typecasting show up on the list. What things are not considered OOP?
None of them are OOP. Those are things that present in OO and non-OO programming. C++ templates are not an object-oriented feature, either (by their nature they are macros that operate on types), they just happen to be a language feature that is applied only in the context of polymorphism, what makes the results of their application object-oriented. You can add templates to assembly, Forttran, Basic, without changing the nature of those languages. Yeah, I can see it -- COMMON blocks from FORTRAN IV with templates. It would work. I would not be surprised if someone wrote a preprocessor that does something like that.
"non-OOP programs may be one "long" list of statements (or commands). With designs of this sort, it is common for some of the program's data to be 'global....means that bugs can have wide-reaching effects."
This is not about monopoly abuse. I mean if Microsoft is demanding that vendors do not offer refunds to consumers as the Vendor has written into their contracts then maybe that is monopoly abuse. Or if microsoft is threatening sactions against those vendors that do honour the refunds... then yes it is monopoly abuse.
Are you INSANE??? Of course, vendors don't have to foot the bill for refunds. Microsoft produces Windows, so refunds have to happen at Microsoft expense, just like with any other product. Microsoft does not allow vendors or consumers to return its product for refund, and does not allow vendors to re-stock returned Windows licenses for use on other products (what any other vendor of any other product would do) so it's entirely Microsoft's doing.
I would agree with all of this except that Xfce also fits your items 4 and 5.
Current Xubuntu + current Compiz = Nothing works. And there is more to compiz than spinning cubes.
1. There are many other Ubuntu derivatives that as far as I know never had direct support from Canonical. Kubuntu is not going to disappear just because it is now at the same level as Xubuntu, Edubuntu, Lubuntu and other projects.
2. Kubuntu itself is an installer, KDE customizations and a set of dependencies. As long as Canonical (or anyone) supports KDE packages, it is at the same level of "legitimacy" as KDE support in Debian.
3. Oh, it's anti-Linux propaganda worker Brian Proffitt again. Figures.
4. Canonical made a really bad move with Unity that was followed with a worse move by Gnome. This leaves KDE as the best desktop environment currently supported by developers.
5. Kubuntu remains the only Ubuntu-derived distribution that supports sane window management, and can be reasonably customized (with Compiz instead of kwin). It's also the best desktop Linux distribution that currently exists.
Be thankful that Microsoft existed.
I am more thankful for Black Plague and Inquisition than I am thankful for Microsoft.
The created the entire PC industry.
Actually Apple did that. Then IBM. Microsoft merely acted as a parasite on IBM.
Without them you would be out of a job.
Without them shitting up every computer-related industry, I would have a much better job.