They are irrelevant; it is just too damn new and unproven. It's a toy language whose only recommendation is that it has Microsoft backing. If some hacker invented the same thing in his bedroom, would it end up being proposed for a curriculum a couple of years later?
I have no problem with corporate backing of schools in exchange for advertizing rights. But the school has no right to sell out what it does not own, namely the minds of the students. If they want to do that, they should get the students to sign an agreement which says: ``your tuition alone is insufficient to cover our expenses. By signing this agreement, you relinquish your mind to us, so we can waste it on crap pushed by our sponsors, like bad programming languages.''
The students don't have to use Microsoft's compiler. This is a very stupid move on Microsoft's part, because it just generates bad publicity, without any payoff. They think that they can own a programming language and somehow exert control through that ownership. Right, the same way Stroustrup controls the activities of thousands of Visual C++ developers. And hey, those C coders won't twitch a finger without Dennis Ritchie's approval.
As for migration, Meta-CVS can import snapshots and figure out file moves. So it can ``reverse engineer'' those simulated renames you did in your CVS project by removing and adding. You just need to feed it a sequence of snapshots.
Unfortunately, Meta-CVS runs only under Linux; but that will change with increasing popularity.
People who put software under the GPL don't believe in garbage like this. It's inconceivable that litigation would ever arise from someone loading a program into someone else's RAM. Nobody in their right mind would consider this to be redistribution. It's clearly an instance of *use*. *You* are interacting with that computer, *you* are using the program that is loaded into RAM. It's not the case that you are denying anyone else his or her rights to that program.
Only proprietary software vendors play these stupid use licensing games, such as requiring N licenses for an running a program on an N-way multiprocessor machine, or making licenses non-transferrable among machines, etc.
You don't have to accept any license to use the GPL'ed software. Only people who redistribute should understand the license, because it only covers that activity. Doh!
Symantec makes anti-virus software. The technical success of such software depends on information about viruses. The commercial success of such sofware depends on the vendor having information about viruses that other organizations or people do not have!
If people can freely exchange information about viruses, they can also develop their own anti-virus solutions independently of the vendors of anti-virus software.
One more point. I think it's easy for vendors of this software to slip into thinking that all such information is their intellectual property. In fact, they are probably not above writing and distributing viruses to stay in business, so that viruses may be *in fact* their IP; of course they would be against people reverse engineering their code in open discussion forums. Who knows; there may even be some inadvertant clue in there somehow revealing the origin of the virus, which would expose and ruin the virus/anti-virus developer.
The primary enduring effect is that we now have a whole bunch of crackpots who keep insisting that some mysterious changes have taken place tranforming the whole world. These changes are a psychological phenomenon that factors only in *some* people's lives. Then there are those who don't perceive any changes, but simply repeat the message that there are changes without thinking critically, like the crowd of people in the well-known story about the Emperor's new clothes. Whenever a sufficient number of people claim to perceive something, there are those who pretend to also perceive it for fear of being seen as strange, stupid or lacking in perception. The net effect is a mass self-bullshitting.
The secondary enduring effect is that some psychotic, paranoid redneck idiots are using September's attacks as an excuse to increase their destructive interference in other people's lives in the name of national security, patriotism or whatever.
If you want to improve parallelism when people work on different pieces of the same program, try to stabilize the interfaces early. Then two or more developers can walk away and do their thing independently of the others: they are all dependent on the interfaces which change very little, and not on each other.
This is not quite the same thing as merely decomposing a program into modules. It's decomposing a program into modules which have well-defined interfaces that have an identity of their own. But there are other things that are interfaces.
An interface is convention by which two parts of an application relate to each other: a set of functions with given arguments and semantics; messages exchanged over a network; file formats or database schemas, directory structure layouts, names of files, language syntaxes, and so on. Essentially anything which has structure and which is formed in one place, and interpreted in another. All such structures create dependencies, and the dependencies must be identified and managed if you want to know how to parallelize development.
The way I understand the text of this article is that the patches have to be reworked several times. This is integration work, not submission work. The developer makes a change which depends on some other change, but rather than waiting for that other change, just goes ahead and does it. Then when the dependent change comes in, the patch is wrong and has to be reworked. Am I close?
The reason it isn't concurrent is because you have people separately working on patches, but those patches are dependend on one another, so their ordering matters. When ordering matters, the situation is sequential, not parallel. The whole bit about air traffic control and sequence numbers is about serializing the parallel development.
The trick is to decompose the development task into chunks that are in fact parallelizable. In turn, those chunks may have sub-chunks which are not parallelizable; those chunks should be perhaps done by one developer, in the correct order.
No developer should wait around for another's patch, and nobody should develop anything that he or she knows will soon be invalidated by a forthcoming patch so badly that it will have to be substantially reworked. If a unit of work depends on some forthcoming patch so badly, a developer should find something else to work on until that patch arrives. How you know that the patch has arrived is by monitoring your e-mail, or scanning the version control system for changes. The other developers should know that someone is waiting for their patch in order to do the next, dependent part of the change, and broadcast it to the team when they are done.
Just because there appears to be a correlation between sleep hours and longevity, even a statistically relevant correlation---one which cannot readily be attributed to chance---does not mean that there is a cause and effect relationship. There is no reason to conclude that sleeping less will prolong one's life, because it's not clear that sleeping longer shortens it. Assuming that the finding is valid, it's possible, and IMHO more likely, that there is some common cause which gives rise to sleeping more and living less, and merely sleeping less won't eradicate that cause. We can probably rule out the third possibility that longevity causes less sleep, however.:):)
Your defence of C and C++ is rational, but unnecessary. These are stone age languages designed for embedded programming. They don't have to have an excuse for lack of abstraction-making.
The point is not that the Lisp solution is elegant, but that it's as seamless as a built in language feature. This only looks elegant on a small scale, for something trivial. When it comes to non-trivial applications, it's more then elegant: it's essential. It's easy to mistake having the right abstraction for mere elegance.
A while loop done at the right level of abstraction requires the user to only be aware of three juxtaposed elements: some symbol to indicate that a while loop is to take place, a controlling expression, and a group of expressions to evaluate repeatedly while that expression is true. These expressions must be evaluated in the same context as they would be if the while loop were absent, otherwise you don't have a clean abstraction. They must be located together in the while loop.
My argument was never that you *can't* implement the *behavior* of ``while looping'' in these other languages, only that you can't implement the actual abstraction of the while loop. That's a big difference. Turing equivalence is completely irrelevant when you are looking at human productivity. No sane programamer would use the horrible pseudo-while-loops that were proposed in this thread. It would be easier, cleaner and more readable to just use if and goto, if those were available.
A robot programming could be equally productive in a variety of different programming languages, because that robot could use an ideal language in its brain, do the compiling internally, and then type out the volumes of crap in some given language to get the job done. A few humans are able to do something resembling this, but even they cannot understand their results months later, when their ``internal'' program has faded from their memory, and none of it had been communicated to others.
What we human programmers need is for the abstractions to be pushed out of the brain and into the language. In the language, the abstractions can be correctly and reliably automated, and communicated to others.
[Sorry about the ugly plain text formatting, but it's sometimes the only way to get code examples in properly on SlashDot.]
I hope it's obvious to you how inferior this is. The real while loop doesn't require you to package up your test and body as a function. When you do that, you have introduced a problem of context, which breaks the abstraction.
By the way, in Common Lisp, you CAN implement the while loop as a function, and yet provide it as a ``language-level'' abstraction as well. Here is how:
(defmacro while (expr &body body)
`(while-func #'(lambda (),expr) #'(lambda (),@body)))
So you can now write something like this loop, which prints numbers from 0 to 9:
(let ((i 0))
(while (< i 10) (print i) (incf i)))
Note how the while body can still refer refer to the local variable i, even though our implementation choice was to package up the expressions and use a function. This is the crucial difference, which sets this apart from the solution that uses functions only. Nobody would use your proposed while loop class, because they would have to carve their program into functions in a completely stupid way, with no access to local variables. Even if you had closures in the language, people wouldn't use it; if you gave a Lisp programmer the above while-func only, he or she would find it necessary to invent the while macro to actualy make it easy to use.
Now to respond to your comment:
> But since there's already a built-in while, what was with the stupid fake example?
Sorry that I touched some sore nerves. I just wanted to pick a very simple example of an extremely simple control abstraction that cannot be implemented in these languages; it's not relevant that they already have it, because the implication is that it's impossible to make other abstractions that they do NOT have.
>What are you trying to prove? That these languages are geared towards efficiency and
>readable syntax instead of generalized object-oriented programming? Well, if so
>you're right.
Not at all. The point is that they have limited abstraction-making ability, because you are stuck with one rigid syntax. I won't respond to your remark about efficiency, whatever you mean by that. (Execution efficiency? Programmer efficiency?)
When you have a rigid syntax, the language is good for certain domains. When you try to solve certain problems, though, the rigidity will get in your way. You may have readability at the microscopic level, due to the use of a small repertoire of built-in syntactic forms, but that readability will be drowned in the morass of code that you will have to crank out. Remember, assembly language is readable too. You have a few instructions, a few addressing modes and everything is in nice columns. But once you crank out a large body of assembly language, it may still be readable, but it's not *grokkable*. Whereas the corresponding C program may be quite grokkable.
It's not true that there exists some simple linear power spectrum along which all languages can be neatly lined up.
What is relevant is this: does the language support all the right abstractions so that the programming solution to a given problem within a given domain can be expressed using elements that closely correspond to the ideal objects understood by the experts in that problem domain.
Now a language that does this may be very domain-specific, and not flexible at all for solving problems in other domains. Or it may be very flexible so that it allows abstractons to be created to new domains that were not even known when that language was created.
So, returning to the vague notion of power, when can we at least tentatively say that one language is more powerful than another? When for a large body of different problems, that language can rise to the occasion and provide the ideal abstractions for expressing the solutions for those problems, whereas the other language fails to do so, and only for a few, if any, problems the reverse is true.
Lastly, what does it mean to have the ideal abstraction? It means not to worry about managing the representational or procedural details of the computation that are not relevant to the solution domain, or having to transform, rename, reshape, reinterpret anything. Unfortunately, this rules out nearly all languages whose only abstraction-making mechanism is making class or function libaries, because not every abstraction in a problem domain neatly corresponds to an object with methods. Only languages which are programmable---meaning that they allow you to write your own sublanguages and provide them as easily as function libraries to other programmers---can support this shape shifting, to produce abstractions to unforseen domains. People can develop custom sublanguages for anything: solving logic problems, querying databases, composing music, generating markup, whatever. You can do these things with object frameworks, but then you lose abstraction; the object programming gadgets rear their ugly head with details like what to instantiate and how to hook it up to something else, etc.
Think about your while() loop in C or Java. The while loop is an ancient abstraction of control flow that someone had to invent. Yet your objects are not powerful enough to implement even this simple abstraction from scratch; you can't make a ``WhileClass'' whose instances do the job of a while loop.
Branching notation should be clear and to the point. CVS has it's magic numbers, StarTeam has god awful views. Let me choose the numbering scheme, don't play games with odd/even numbering. Version numbers should not be overloaded to carry additional meta-information by the product.
This is incorrect. The CVS numbers are internal. If you care about them at all, you are doing something wrong. Your baselines and branches are identified by tags. If you understand how the CVS numbers work, they are actually quite logical; there are reasons why they work they way they do. It's not play ``games''.
Version numbers *are* meta-information, so it's meaningless to talk about them being overloaded with metainformation. They are not intended to correspond to your product release numbers, which are usually the fabrications of a marketing department anyway, like e.g. Solaris 7 being the followup to 2.6. Do you think the Sun guys bumped up their version control system to use the number 7?;)
Adds renaming over top of CVS and some other niceties. Can be used to create patches that contain versioning changes. With Meta-CVS, people can restructure directories in conflicting ways, and then resolve conflicts when they merge the structure.
http://users.footprints.net/~kaz/mcvs.html
This doesn't add anything else; no atomic commits or distributed operation over multiple repositories, etc.
Of course, you can use branches to track foreign code streams, as you can with CVS. The nice thing is that you can rename things on your own branch and keep up with an unrenamed source of patches. Or if the other people are using Meta-CVS, they can give you patches that include restructuring.
Meta-CVS is currently about 1600 physical lines of Common Lisp (with some CLISP extensions and bindings to glibc2) scattered in twenty or so files. A lot is done with little!
If you want a successful project, choose solid, mature implementations of equally mature programming languges.
You could succeed anyway, but then you could be a successful pianist with three missing fingers too. That doesn't mean you want to deliberately chop off three fingers.:)
There is no statistically valid reason to conclude that the boy's condition is caused by the use of a vibrating game controller. That boy is a sample of one. Of course the idiotic media love to dig up the slightest piece of bad news and blow it out of proportion.
What you need is random sampling of many game players to see whether there is a statistical correlation between use of a vibrating controller and the health symptoms related to vibration. And of course, even given a correlation, you have not determined cause-and-effect; when two findings are correlated, they could have some hidden common cause.
It's hardly news that GCC is beat on benchmarks by this compiler or that. When has this not been the case?
When you see claims like that being made, try to think of factors that were not included in the analysis:
- architecture support. Does the benchmarked compiler have back ends for every architecture that GCC supports?
- diagnostics: does it diagnose code as well?
- conformance: how well does it comply to ISO C
and C++? Does it have a standard library, or at least integrate with one?
- correctness: can it be trusted to generate
correct code, even when aggressively optimizing?
Are some of the benchmark results depending on a fluke, such as unwarranted assumptions about object aliasing which just happen to be true?
- extensions: does it provide a consistent set of extensions across all the architectures it supports?
A project like the Linux kernel supports many architectures, and also needs certain extension from the compiler. Some of the extensions are darn useful, like the GCC inline assembly syntax which can allocate registers for you, and tightly weave your machine sequence into surrounding code. You wouldn't want the kernel to require a completely different compiler for each architecture.
- do any of the optimizations affect binary compatibility among modules (calling sequences, object layouts).
- how many language front ends does the competing compiler have? Is it C or C++ only, or are other languages supported?
- Is the source code open? Can anyone who is willing to invest the time and energly retarget the compiler?
- How well does its generated code run on older chip family members, like the Pentium, 486 or 386? That could be important for some embedded work.
- Can it sacrifice speed and optimize for size?
There is no way that another compiler can replace GCC all that easily. Think about what it takes to compile every component of a GNU/Linux system: the kernel, libraries, and tons of programs. Even with support for all of GCC's extensions, there is the matter of confidence.
Remember, the kernel started out in Borland C.
on
Borland C++ For Linux
·
· Score: 3, Informative
Linus used a Borland compiler to bootstrap the development of Linux, because Minix was compiled with that. (Then when the system was good enough to host GCC, and serve as its own development platform, that compiler was abandoned).
They are irrelevant; it is just too damn new and unproven. It's a toy language whose only recommendation is that it has Microsoft backing. If some hacker invented the same thing in his bedroom, would it end up being proposed for a curriculum a couple of years later?
I have no problem with corporate backing of schools in exchange for advertizing rights. But the school has no right to sell out what it does not own, namely the minds of the students. If they want to do that, they should get the students to sign an agreement which says: ``your tuition alone is insufficient to cover our expenses. By signing this agreement, you relinquish your mind to us, so we can waste it on crap pushed by our sponsors, like bad programming languages.''
The students don't have to use Microsoft's compiler. This is a very stupid move on Microsoft's part, because it just generates bad publicity, without any payoff. They think that they can own a programming language and somehow exert control through that ownership. Right, the same way Stroustrup controls the activities of thousands of Visual C++ developers. And hey, those C coders won't twitch a finger without Dennis Ritchie's approval.
mcvs mv foo.c bar.c
As for migration, Meta-CVS can import snapshots and figure out file moves. So it can ``reverse engineer'' those simulated renames you did in your CVS project by removing and adding. You just need to feed it a sequence of snapshots.
Unfortunately, Meta-CVS runs only under Linux; but that will change with increasing popularity.
That is a psychological problem, not an
actual tool problem.
http://freshmeat.net/projects/mcvsf ootprints.net/~kaz/mcvs
http://users.
Could programming language ignorance or bigotry be at least partially at the root of this? Probably not, but one wonders anyway.
People who put software under the GPL don't believe in garbage like this. It's inconceivable that litigation would ever arise from someone loading a program into someone else's RAM. Nobody in their right mind would consider this to be redistribution. It's clearly an instance of *use*. *You* are interacting with that computer, *you* are using the program that is loaded into RAM. It's not the case that you are denying anyone else his or her rights to that program.
Only proprietary software vendors play these stupid use licensing games, such as requiring N licenses for an running a program on an N-way multiprocessor machine, or making licenses non-transferrable among machines, etc.
You don't have to accept any license to use the GPL'ed software. Only people who redistribute should understand the license, because it only covers that activity. Doh!
and nobody notices. :)
Symantec makes anti-virus software. The technical success of such software depends on information about viruses. The commercial success of such sofware depends on the vendor having information about viruses that other organizations or people do not have!
If people can freely exchange information about viruses, they can also develop their own anti-virus solutions independently of the vendors of anti-virus software.
One more point. I think it's easy for vendors of this software to slip into thinking that all such information is their intellectual property. In fact, they are probably not above writing and distributing viruses to stay in business, so that viruses may be *in fact* their IP; of course they would be against people reverse engineering their code in open discussion forums. Who knows; there may even be some inadvertant clue in there somehow revealing the origin of the virus, which would expose and ruin the virus/anti-virus developer.
The primary enduring effect is that we now have a whole bunch of crackpots who keep insisting that some mysterious changes have taken place tranforming the whole world. These changes are a psychological phenomenon that factors only in *some* people's lives. Then there are those who don't perceive any changes, but simply repeat the message that there are changes without thinking critically, like the crowd of people in the well-known story about the Emperor's new clothes. Whenever a sufficient number of people claim to perceive something, there are those who pretend to also perceive it for fear of being seen as strange, stupid or lacking in perception. The net effect is a mass self-bullshitting.
The secondary enduring effect is that some psychotic, paranoid redneck idiots are using September's attacks as an excuse to increase their destructive interference in other people's lives in the name of national security, patriotism or whatever.
If you want to improve parallelism when people work on different pieces of the same program, try to stabilize the interfaces early. Then two or more developers can walk away and do their thing independently of the others: they are all dependent on the interfaces which change very little, and not on each other.
This is not quite the same thing as merely decomposing a program into modules. It's decomposing a program into modules which have well-defined interfaces that have an identity of their own. But there are other things that are interfaces.
An interface is convention by which two parts of an application relate to each other: a set of functions with given arguments and semantics; messages exchanged over a network; file formats or database schemas, directory structure layouts, names of files, language syntaxes, and so on. Essentially anything which has structure and which is formed in one place, and interpreted in another. All such structures create dependencies, and the dependencies must be identified and managed if you want to know how to parallelize development.
The way I understand the text of this article is that the patches have to be reworked several times. This is integration work, not submission work. The developer makes a change which depends on some other change, but rather than waiting for that other change, just goes ahead and does it. Then when the dependent change comes in, the patch is wrong and has to be reworked. Am I close?
The reason it isn't concurrent is because you have people separately working on patches, but those patches are dependend on one another, so their ordering matters. When ordering matters, the situation is sequential, not parallel. The whole bit about air traffic control and sequence numbers is about serializing the parallel development.
The trick is to decompose the development task into chunks that are in fact parallelizable. In turn, those chunks may have sub-chunks which are not parallelizable; those chunks should be perhaps done by one developer, in the correct order.
No developer should wait around for another's patch, and nobody should develop anything that he or she knows will soon be invalidated by a forthcoming patch so badly that it will have to be substantially reworked. If a unit of work depends on some forthcoming patch so badly, a developer should find something else to work on until that patch arrives. How you know that the patch has arrived is by monitoring your e-mail, or scanning the version control system for changes. The other developers should know that someone is waiting for their patch in order to do the next, dependent part of the change, and broadcast it to the team when they are done.
Just because there appears to be a correlation between sleep hours and longevity, even a statistically relevant correlation---one which cannot readily be attributed to chance---does not mean that there is a cause and effect relationship. There is no reason to conclude that sleeping less will prolong one's life, because it's not clear that sleeping longer shortens it. Assuming that the finding is valid, it's possible, and IMHO more likely, that there is some common cause which gives rise to sleeping more and living less, and merely sleeping less won't eradicate that cause. We can probably rule out the third possibility that longevity causes less sleep, however. :) :)
Your defence of C and C++ is rational, but unnecessary. These are stone age languages designed for embedded programming. They don't have to have an excuse for lack of abstraction-making.
The point is not that the Lisp solution is elegant, but that it's as seamless as a built in language feature. This only looks elegant on a small scale, for something trivial. When it comes to non-trivial applications, it's more then elegant: it's essential. It's easy to mistake having the right abstraction for mere elegance.
A while loop done at the right level of abstraction requires the user to only be aware of three juxtaposed elements: some symbol to indicate that a while loop is to take place, a controlling expression, and a group of expressions to evaluate repeatedly while that expression is true. These expressions must be evaluated in the same context as they would be if the while loop were absent, otherwise you don't have a clean abstraction. They must be located together in the while loop.
My argument was never that you *can't* implement the *behavior* of ``while looping'' in these other languages, only that you can't implement the actual abstraction of the while loop. That's a big difference. Turing equivalence is completely irrelevant when you are looking at human productivity. No sane programamer would use the horrible pseudo-while-loops that were proposed in this thread. It would be easier, cleaner and more readable to just use if and goto, if those were available.
A robot programming could be equally productive in a variety of different programming languages, because that robot could use an ideal language in its brain, do the compiling internally, and then type out the volumes of crap in some given language to get the job done. A few humans are able to do something resembling this, but even they cannot understand their results months later, when their ``internal'' program has faded from their memory, and none of it had been communicated to others.
What we human programmers need is for the abstractions to be pushed out of the brain and into the language. In the language, the abstractions can be correctly and reliably automated, and communicated to others.
What if you don't know upfront what the project's needs or goals are?
;)
Anyway, show that implementation of while in Java, ``while'' we are at it.
[Sorry about the ugly plain text formatting, but it's sometimes the only way to get code examples in properly on SlashDot.]
:again
:again))
,expr) #'(lambda () ,@body)))
I hope it's obvious to you how inferior this is. The real while loop doesn't require you to package up your test and body as a function. When you do that, you have introduced a problem of context, which breaks the abstraction.
By the way, in Common Lisp, you CAN implement the while loop as a function, and yet provide it as a ``language-level'' abstraction as well. Here is how:
(defun while-func (expr-fun body-fun)
(tagbody
(cond
((funcall expr-fun)
(funcall body-fun)
(go
(t (return-from while-func (values))))))
(defmacro while (expr &body body)
`(while-func #'(lambda ()
So you can now write something like this loop, which prints numbers from 0 to 9:
(let ((i 0))
(while (< i 10) (print i) (incf i)))
Note how the while body can still refer refer to the local variable i, even though our implementation choice was to package up the expressions and use a function. This is the crucial difference, which sets this apart from the solution that uses functions only. Nobody would use your proposed while loop class, because they would have to carve their program into functions in a completely stupid way, with no access to local variables. Even if you had closures in the language, people wouldn't use it; if you gave a Lisp programmer the above while-func only, he or she would find it necessary to invent the while macro to actualy make it easy to use.
Now to respond to your comment:
> But since there's already a built-in while, what was with the stupid fake example?
Sorry that I touched some sore nerves. I just wanted to pick a very simple example of an extremely simple control abstraction that cannot be implemented in these languages; it's not relevant that they already have it, because the implication is that it's impossible to make other abstractions that they do NOT have.
>What are you trying to prove? That these languages are geared towards efficiency and
>readable syntax instead of generalized object-oriented programming? Well, if so
>you're right.
Not at all. The point is that they have limited abstraction-making ability, because you are stuck with one rigid syntax. I won't respond to your remark about efficiency, whatever you mean by that. (Execution efficiency? Programmer efficiency?)
When you have a rigid syntax, the language is good for certain domains. When you try to solve certain problems, though, the rigidity will get in your way. You may have readability at the microscopic level, due to the use of a small repertoire of built-in syntactic forms, but that readability will be drowned in the morass of code that you will have to crank out. Remember, assembly language is readable too. You have a few instructions, a few addressing modes and everything is in nice columns. But once you crank out a large body of assembly language, it may still be readable, but it's not *grokkable*. Whereas the corresponding C program may be quite grokkable.
What is relevant is this: does the language support all the right abstractions so that the programming solution to a given problem within a given domain can be expressed using elements that closely correspond to the ideal objects understood by the experts in that problem domain.
Now a language that does this may be very domain-specific, and not flexible at all for solving problems in other domains. Or it may be very flexible so that it allows abstractons to be created to new domains that were not even known when that language was created.
So, returning to the vague notion of power, when can we at least tentatively say that one language is more powerful than another? When for a large body of different problems, that language can rise to the occasion and provide the ideal abstractions for expressing the solutions for those problems, whereas the other language fails to do so, and only for a few, if any, problems the reverse is true.
Lastly, what does it mean to have the ideal abstraction? It means not to worry about managing the representational or procedural details of the computation that are not relevant to the solution domain, or having to transform, rename, reshape, reinterpret anything. Unfortunately, this rules out nearly all languages whose only abstraction-making mechanism is making class or function libaries, because not every abstraction in a problem domain neatly corresponds to an object with methods. Only languages which are programmable---meaning that they allow you to write your own sublanguages and provide them as easily as function libraries to other programmers---can support this shape shifting, to produce abstractions to unforseen domains. People can develop custom sublanguages for anything: solving logic problems, querying databases, composing music, generating markup, whatever. You can do these things with object frameworks, but then you lose abstraction; the object programming gadgets rear their ugly head with details like what to instantiate and how to hook it up to something else, etc.
Think about your while() loop in C or Java. The while loop is an ancient abstraction of control flow that someone had to invent. Yet your objects are not powerful enough to implement even this simple abstraction from scratch; you can't make a ``WhileClass'' whose instances do the job of a while loop.
This is incorrect. The CVS numbers are internal. If you care about them at all, you are doing something wrong. Your baselines and branches are identified by tags. If you understand how the CVS numbers work, they are actually quite logical; there are reasons why they work they way they do. It's not play ``games''.
Version numbers *are* meta-information, so it's meaningless to talk about them being overloaded with metainformation. They are not intended to correspond to your product release numbers, which are usually the fabrications of a marketing department anyway, like e.g. Solaris 7 being the followup to 2.6. Do you think the Sun guys bumped up their version control system to use the number 7? ;)
Adds renaming over top of CVS and some other niceties. Can be used to create patches that contain versioning changes. With Meta-CVS, people can restructure directories in conflicting ways, and then resolve conflicts when they merge the structure.
http://users.footprints.net/~kaz/mcvs.html
This doesn't add anything else; no atomic commits or distributed operation over multiple repositories, etc.
Of course, you can use branches to track foreign code streams, as you can with CVS. The nice thing is that you can rename things on your own branch and keep up with an unrenamed source of patches. Or if the other people are using Meta-CVS, they can give you patches that include restructuring.
Meta-CVS is currently about 1600 physical lines of Common Lisp (with some CLISP extensions and bindings to glibc2) scattered in twenty or so files. A lot is done with little!
If you want a successful project, choose solid, mature implementations of equally mature programming languges.
:)
You could succeed anyway, but then you could be a successful pianist with three missing fingers too. That doesn't mean you want to deliberately chop off three fingers.
There is no statistically valid reason to conclude that the boy's condition is caused by the use of a vibrating game controller. That boy is a sample of one. Of course the idiotic media love to dig up the slightest piece of bad news and blow it out of proportion.
What you need is random sampling of many game players to see whether there is a statistical correlation between use of a vibrating controller and the health symptoms related to vibration. And of course, even given a correlation, you have not determined cause-and-effect; when two findings are correlated, they could have some hidden common cause.
It's hardly news that GCC is beat on benchmarks by this compiler or that. When has this not been the case?
When you see claims like that being made, try to think of factors that were not included in the analysis:
- architecture support. Does the benchmarked compiler have back ends for every architecture that GCC supports?
- diagnostics: does it diagnose code as well?
- conformance: how well does it comply to ISO C
and C++? Does it have a standard library, or at least integrate with one?
- correctness: can it be trusted to generate
correct code, even when aggressively optimizing?
Are some of the benchmark results depending on a fluke, such as unwarranted assumptions about object aliasing which just happen to be true?
- extensions: does it provide a consistent set of extensions across all the architectures it supports?
A project like the Linux kernel supports many architectures, and also needs certain extension from the compiler. Some of the extensions are darn useful, like the GCC inline assembly syntax which can allocate registers for you, and tightly weave your machine sequence into surrounding code. You wouldn't want the kernel to require a completely different compiler for each architecture.
- do any of the optimizations affect binary compatibility among modules (calling sequences, object layouts).
- how many language front ends does the competing compiler have? Is it C or C++ only, or are other languages supported?
- Is the source code open? Can anyone who is willing to invest the time and energly retarget the compiler?
- How well does its generated code run on older chip family members, like the Pentium, 486 or 386? That could be important for some embedded work.
- Can it sacrifice speed and optimize for size?
There is no way that another compiler can replace GCC all that easily. Think about what it takes to compile every component of a GNU/Linux system: the kernel, libraries, and tons of programs. Even with support for all of GCC's extensions, there is the matter of confidence.
Linus used a Borland compiler to bootstrap the development of Linux, because Minix was compiled with that. (Then when the system was good enough to host GCC, and serve as its own development platform, that compiler was abandoned).