By the way- another advantage to having a stable kernel API layer is the ability to write a dead-tree book about how to write Linux device drivers and not have it be obsolete by the time it gets published. I have half a dozen books on this subject- half of them were obsolete by the time they were published, they're all obsolete now.
There's a joke- programming is a lot like sex. One mistake, and you're supporting it for the rest of your life. By this measure, writting a device driver for Linux is a mistake. Because even after the feature set and the hardware itself is stable, you are letting yourself into a never-ending task of constantly changing the driver to keep track of the current API changes. At a previous job we spec'd it out at about 1/2 of a full time position to keep up with all the kernel changes. This is your job, from now until eternity, or at least until you're willing to have the driver declared obsolete and abandoned (after all, we all know that there is just three types of software- vapor, beta, and obsolete).
Well, congratulations. You have your religous purity. And guess what- it's comming at a cost. You wonder why Linux isn't more popular on the desktop? Well, here's part of the reason. It's hardware support will always- ALWAYS- be behind that of Windows. Why? Because when the hardware ships, it ships with Windows drivers that the hardware vendor wrote with it. Note that Windows pulls the same sort of API changing crap that Linux does. The difference is that the hardware vendors look at Windows, and the half man-year per year cost of supporting Windows costs, and go "but we have to support Windows if we want to sell more than 3 units." They then look at Linux, and the half man-year per year cost of support Linux, and go "Supporting Linux is not cost-effective at this time." I know, because I've seen this happen. So now the hardware is out there. And now we wait, for someone willing to step up and volunteer the time to write, and maintain indefinately, the driver. Someone less capable of doing it than the hardware manufacturer (this isn't to question the capabilities of the current kernel developers, but the fact of the matter is that there is a huge advantage to being three cubes down from the hardware developers, and capable of wandering over and asking direct questions, instead of having to reverse engineer what is really going on, having worked both ways).
So this is the fundamental question: which is worse. Having binary-only proprietary drivers, or being forever behind in hardware support and not having people contribute simply because they don't feel like having to constantly update the driver once they finish it, they'd like to be able to move on. I come down on one side, Linus and the kernel developers down on the other.
the people who keep telling me allocation in Java is slow (much slower than 10 instructions) are generally experienced Java programmers. I use Ocaml, so I'm quite aware of how fast a generational garbage collector can be (btw, on the x86 in Ocaml, allocations are only 5 simple instructions). But from all first hand reports I've heard, Java allocation is still slow. It may be faster than C++, but it's still slow.
I freely and publically admit to being one of the people who said that no way would Apple be that stupid. I was wrong- Apple was that stupid.
This will kill Apple. People generally only buy all new software and all new hardware at the same time when their old systems have died. And fat binaries have been tried numerous times, I've yet to see the market accept them.
My apologies. I was wrong. I though Apple had a clue.
I agree- but that isn't why overclocking is interesting. Overclocking is a good measure of the possibility of near-term clock speed bumps. From reading the article, it looks like the Opteron can basically go to 2.7Ghz just about anytime AMD feels like, it can probably go to 2.8GHz, and we may see FX-59 or -61 CPUs passing 3GHz in the near future.
Fortunately, a shooting match between the two sets of claimants assisted the title slightly by reducing the original number to six and substituting eleven sets of descendants.
Personally, I don't care. I currently live a Microsoft-free life. Except that I also use email- and my email box is cluttered with spam comming from zombied Windows boxes, and virii sent to me by infected Windows machines. So yes, you running Windows does effect me, in a very negative way.
Having to differentiate between HashTable.insert and SkipList.insert sort of defeats the purpose of abstract types, because no one thought to make module signatures themselves first-class (except Alice).
I've never seen a real good reason this is usefull, myself (and yes, Virginia, I have done signifigant programming in C++ and other languages with this ability). Many data structures have the same or similiar implementations, but generally different performance characteristics. When I use a particular data structure, it's because I want those performance characteristics, and not others. Replacing the data structure I choose with another with different performance characteristics is likely to cause performance degredation, possibly severe performance degredation- like converting an O(N) algorithm into an O(N^2) algorithm.
The classic example of this is lists and arrays. Both data structures have a "get the i-th element" operation, and both can have a "prepend a element" operation. With arrays, the ith operation is O(1), but the prepend operation is O(N) (I have to move all elements of the list out of the way to make room for the new head element). With lists, the ith operation is O(N) (I have to walk down the list), but the prepend operation is O(1). If my algorithm is heavily dependent up getting the ith elemenet, and never or almost never prepends an element, then I want to use arrays and stay far away from lists. If my algorithm prepends elements a lot, and never or rarely, goes and gets the ith element, then I want lists and not arrays. This is exactly the problem the original poster fell into (well, one of them anyways).
Generic implementations of algorithms? Rare, in my experience. Rare to the point that duplicating the code is a legitimate alternative. I mean, consider sorting both lists and arrays. OK, with a little bit of trickery, you could probably write a bubble sort that was (more or less) equally efficient on both lists and arrays. But anything more complicated? OK, let's just limit it to linked lists. For singly linked lists, you basically need to do merge sort. But for doubly linked lists, I've written a variant of heap sort that is twice as fast as merge sort (you treat the next and previous pointers as left and right child pointers, convert the list into a true pointer based heap, and run heap sort on the result).
It's a trade off. I don't see what Ocaml traded off as that valuable- and what Ocaml got in return is strong type checking and type inference. All the benefits of a real type system without the bondage and discipline aspects. All languages are trade offs. If you hold out for having your cake and eating it too, then yes, you will always be dissatisfied.
Having read the article and looked at your Ocaml code, you do have at least one problem in your implementation. You're using lists. Lists are not for random access and modification. To change the nth element of a list, you need to modify (and reallocate) n elements.
Try using a map instead. I'll send you example Ocaml code in a day or two (I'm moving, so I don't have that much free time to fix other people's bugs that I'm not getting paid to fix). Note that this is true in Haskell as well as Ocaml. Haskell may be just a little bit better at hiding the problem with laziness- but it's still a problem!
Now, for the brutal part of the response: that big of a difference in performance almost certain does mean you've messed something up in your implementation. But, instead of saying "Gee- I wonder what I screwed up?" you said "Gee- Ocaml and functional programming must just suck!" That I still fault you for.
We do. In fact, we encourage it. They're called 401K's. Look them up- you can sock away up to 15% of your income, before taxes, for retirement. If that isn't enough, you're free to open up your own IRAs and mutual fund investments, or open up your own stock brokerage account, and invest there for a few dozen dollars a year. If that's too much, you can start investing in DRIP for $5 a month or so. I've never heard of a time in our history when it's been so easy for people to save for their retirement, or have so many ways to do so.
Social Security isn't *investment*, it's *insurance*. It's a gaurentee that you won't have to spend your retirement years under a bridge.
This change will make stock options for anyone except the top most layers of management a thing of the past. You see, stock options are already expensed. The main measure of the value of a company is the Earnings Per Share, or EPS. This is the ratio of the total earnings of the company divided by the number of outstanding shares. Increase the number of shares, and what happens? The EPS drops. But now, if you issue stock options, you get hit twice. You get hit once by falling EPS due to the increased number of shares, and a second time as you have to decrease your earnings by an amount equal to the value of the stock option grant.
The problem with stock options were the immediate grants. The idea behind stock options was to give the people in the company- not just the upper level management, but everyone- a stake in the company. A stake in the long term prospects of the growth- especially if the options you're granted now can't be exercised for five years. All of a sudden not only are you less likely to quit (and lose those options!), you're more concerned about where the company will be five years from now.
The problem is with the CEOs getting multimillion dollar stock grants, on pennies on the dollar, effective immediately. This encourages to pump up next quarter's numbers by any means, hook or crook, so they can dump their stock. And to heck with where the company will be a year, let alone five years from now.
But hey- given a chance to throw the baby out but keep the bathwater, would we pass up the chance?
While it does moderately well on this test (finishing near the middle), you might be surprised at it's weak finish compared to it's reputation as a concise language. Well, as a committed Ocaml advocate, Ocaml isn't a scripting language. I freely admit that it has so-so string handling, no built-in regular expressions, so-so process handling, etc. But this is because it isn't a scripting language- it's an applications language, like C++, Java, and C#. And the only reason it does as well as it does is because it's a signifigantly better language than it's competition.
If you're writting a quick script to grep through the log files looking for port scanners, Ocaml is the wrong language.
Or if they do, they won't last past the first snow. Along comes a snowplow, and *pop* *pop* *pop* there go the reflectors, smart or not, right into the ditch. Along with the odd hunk of concrete that was sticking up, unlucky mailboxes, small cars...
Computers, used correctly, can be a great benefit to education. Take a look at the Teach Scheme project as an example- among other things, they use programming to help teach math.
Educators, however, have to get a few things through their heads:
1) They're teaching life skills, not jobs skills. You don't need the latest and greatest of anything. I learned to write using Wordstar 3.0 on an 8086- Word 2 for Windows on a 133 MHz Pentium is enough, you don't need a 3GHz P-4 with Windows XP. Remember that your average 9th grader is still 8 years from entering the work place- so 2004 technology will be as obsolete when they land their first job as 1996 technology is today. And those 3rd graders? They're 14 years away from getting a job- today's technology will be like using 1990 technology. Windows 95 vr.s Windows XP doesn't matter.
2) Everyone needs to be taught to program. This isn't just a class for upper classmen (notice the *men*) looking to go into technical careers. I don't think 2nd or 3rd grade it too early to start teaching everyone to program- this is the point of the Logo language. And the earlier they come to it, the less strange it will be!
3) The computer needs to be used for more than rote memorization drills. This is the number one failure I see. Computers are, first and foremost, problem solving tools. This is why programming is so important- the *child* should be figuring out ways to get the computer to solve problems in the field being taught. With mathematics, this is easy- add a couple of graphics routines, and all of a sudden geometry comes alive. Algebra is all over programming. The computer has fascinating abilities as a musical instrument. Etc.
As someone who was originally taught to write with pen on paper, I *hated* writting. One mistake and you had to copy the entire page over. Until I discovered computers. Opps- mispelled that word? Just go back and correct it. Hmm- that paragraph is in the wrong spot, let's move it. Don't worry about the details, get the ideas down and fix it later. This is still how I write (it's how I wrote this posting). And instead of hating writting, I enjoy it.
Of course, this requires a lot more computers. Which is why it's important that school systems not buy the latest and greatest (which always cost), but instead can get by on seriously obsolete hardware.
Lots of counter examples, of computers incredibly enhancing education, exist. See especially The Children's Machine by Seymore Papert. But notice how these success stories tend to follow my guidelines much more so than "traditional" education does.
Re:It's Open Mic Night at the Astrophysics Lounge!
on
Melting Europa
·
· Score: 1
It's the falsifiability that makes it usefull for solving problems (curing diseases,etc.). Unlike other Dogmas, science doesn't provide the answers- it only provides the means to find the answers.
An interesting observation is that the theorem "the scientific method is an effective way of understanding the universe" is, itself, a falsifiable theorem, and thus can be investigated scientifically. We can perform experiments and get data telling us wether it's true or not. Actually doing this is left as exercise to the student (hint: consider the historical record).
As I understand the law here in the States (IANAL, etc), being the *unknowning* recipient of stolen property does not make you a criminal, even if you make money off that property. The most that SCO should be able to demand is that certain parts of the kernel be removed. Notice how they're being seriously vague about *what* parts of the kernel are theirs, because otherwise such an effort would already be underway.
The claim that you cannot write a Unix OS without their magic ingredient is pure horsepucky. As any engineer in the industry will tell you. The theory is all out in the open, and little if any of it was developed by SCO.
Assume you have four euclidean points, A, B, C, and D. A, B, and C are colinear, and B, C, and D are colinear.
Assume D is *not* on the line A-B-C. Therefor, the set of points A, B, and D define a plane- if there is a solution, it is on a single plane. Going into n dimensions doesn't help- if there is a solution, it's planar.
But two points define a line. So the A-B-C line can be defined by two points, B and C say. But so can the B-C-D line, indeed by the same two points! The two lines have to share at least two points, therefor D has to be on the A-B-C line.
The trick is the question talked about *pennies*, not euclidean points. This gives us some fudge room, and the solution *must* take advantage of this fudge room. The only other alternative is to leave euclidean geometery. Anyone got a black hole handy?
The problem is that C++ requires basically an infinite k to parse context free. For example, consider what the compiler does when it sees a set of tokens like:
a d;
Now, is this:
a) a strange but legal expression parsed
like:
(a ) d;
Both are legal interpretations. The only way you can tell is by looking at the type of a before parsing the rest of the expression. And even this may not help. IIRC, the issue may be undecidable, as template names are in a different "namespace" than variable names (i.e. I can have both a template type and a variable with the same name at the same time.
Note that d being a more complex expression than just a name also allows you to decide. But we're up to a k=7 on the simple case. Make b and c arbitrarily complex expressions themselves, and you can make k need to be arbitrarily large. Or heck, consider:
a d, e, f; (three new variables d, e, and f, or four different expressions combined with the comma operator?).
And it doesn't matter how infrequent this code construct is. The compiler has to deal with this situation, and situations like it. And deal correctly. C++ simply is not LALR(1) parsable, and likely not really parsable at all. It's a fundamental flaw in the language.
And this does cost. YACC was developed because it's easier to write and maintain parsers in YACC than hand-rolled parsers for any nontrivial but LALR(1) parsable language. Time and effort will go to the development and maintainance of the compilers. For commercial products, this means higher prices. For free products like GCC, this means fewer new features and fewer bugfixes in other parts of the code.
Unless the functions to inline are *real* small. Think about it- if the function is f bytes in size inlined, and f+a bytes in size as a standalone, and it takes c bytes to call the standalone function, and the function is called in n places, then inlining the function everywhere takes f*n bytes, while calling it takes c*n + f + a bytes. If c f - ((f+a)/n), then it'll be cheaper (require fewer code bytes) to not inline f than to inline f. As n gets large, all you need is c f for it to be a win. How many bytes does it take to call a function? That's your target- if your function is more than a few lines of code (at best) you're probably better off not inlining the function.
I'd actually be inclined to go the other direction- is it possible to uninline things? If the code is doing similiar things in different places, is it possible to write a single function which is instead called in both places?
Barring that, other options include using a different complier- does gcc support your processor? I know gcc doesn't support everything under the sun- many 8- and 16-bit micros and DSPs aren't supported, for example. But if gcc is supported, it does pretty good on the stack space management and automatically inlining. Or you just might have to bite the bullet and spring for a larger rom/flash or larger cpu.
It's worse than that. The key to decrypt the software is on the disk, just in a "non-standard" location. Obviously, despite it being non-standard the software can read the location. All the cracker has to do is find out where on the disk it is, and read the key off themselves, and viola.
A better example would be the old floppy-based copy protection schemes where they'd use weird track steppings or other floppy controller timings to try and hide the data. If I recall correctly, all the copy protection schemes based on this failed as well. In fact, I seem to remember "perfect copy" programs that would copy said disks anyways. The only thing new here is that they've add cryptography. Not that it helps.
Of course, now I've gone and violated the DMCA. Hmm. Since the information is stored in a "non-standard" location, I wonder if documenting how to access that location aka documenting the hardware interface to the drive is now a DMCA violation?
By the way- another advantage to having a stable kernel API layer is the ability to write a dead-tree book about how to write Linux device drivers and not have it be obsolete by the time it gets published. I have half a dozen books on this subject- half of them were obsolete by the time they were published, they're all obsolete now.
There's a joke- programming is a lot like sex. One mistake, and you're supporting it for the rest of your life. By this measure, writting a device driver for Linux is a mistake. Because even after the feature set and the hardware itself is stable, you are letting yourself into a never-ending task of constantly changing the driver to keep track of the current API changes. At a previous job we spec'd it out at about 1/2 of a full time position to keep up with all the kernel changes. This is your job, from now until eternity, or at least until you're willing to have the driver declared obsolete and abandoned (after all, we all know that there is just three types of software- vapor, beta, and obsolete).
Well, congratulations. You have your religous purity. And guess what- it's comming at a cost. You wonder why Linux isn't more popular on the desktop? Well, here's part of the reason. It's hardware support will always- ALWAYS- be behind that of Windows. Why? Because when the hardware ships, it ships with Windows drivers that the hardware vendor wrote with it. Note that Windows pulls the same sort of API changing crap that Linux does. The difference is that the hardware vendors look at Windows, and the half man-year per year cost of supporting Windows costs, and go "but we have to support Windows if we want to sell more than 3 units." They then look at Linux, and the half man-year per year cost of support Linux, and go "Supporting Linux is not cost-effective at this time." I know, because I've seen this happen. So now the hardware is out there. And now we wait, for someone willing to step up and volunteer the time to write, and maintain indefinately, the driver. Someone less capable of doing it than the hardware manufacturer (this isn't to question the capabilities of the current kernel developers, but the fact of the matter is that there is a huge advantage to being three cubes down from the hardware developers, and capable of wandering over and asking direct questions, instead of having to reverse engineer what is really going on, having worked both ways).
So this is the fundamental question: which is worse. Having binary-only proprietary drivers, or being forever behind in hardware support and not having people contribute simply because they don't feel like having to constantly update the driver once they finish it, they'd like to be able to move on. I come down on one side, Linus and the kernel developers down on the other.
Fine. Their kernel. Their problem.
the people who keep telling me allocation in Java is slow (much slower than 10 instructions) are generally experienced Java programmers. I use Ocaml, so I'm quite aware of how fast a generational garbage collector can be (btw, on the x86 in Ocaml, allocations are only 5 simple instructions). But from all first hand reports I've heard, Java allocation is still slow. It may be faster than C++, but it's still slow.
With all the horseshit I've seen on this topic, I knew there had to be a pony around here somewhere.
Yum. Fresh crow.
I freely and publically admit to being one of the people who said that no way would Apple be that stupid. I was wrong- Apple was that stupid.
This will kill Apple. People generally only buy all new software and all new hardware at the same time when their old systems have died. And fat binaries have been tried numerous times, I've yet to see the market accept them.
My apologies. I was wrong. I though Apple had a clue.
I agree- but that isn't why overclocking is interesting. Overclocking is a good measure of the possibility of near-term clock speed bumps. From reading the article, it looks like the Opteron can basically go to 2.7Ghz just about anytime AMD feels like, it can probably go to 2.8GHz, and we may see FX-59 or -61 CPUs passing 3GHz in the near future.
Now, secure this OS from malware...
I don't want userspace to be able to hack the kernel. This is one of those ideas that sounds neater than it is.
Personally, I don't care. I currently live a Microsoft-free life. Except that I also use email- and my email box is cluttered with spam comming from zombied Windows boxes, and virii sent to me by infected Windows machines. So yes, you running Windows does effect me, in a very negative way.
I've never seen a real good reason this is usefull, myself (and yes, Virginia, I have done signifigant programming in C++ and other languages with this ability). Many data structures have the same or similiar implementations, but generally different performance characteristics. When I use a particular data structure, it's because I want those performance characteristics, and not others. Replacing the data structure I choose with another with different performance characteristics is likely to cause performance degredation, possibly severe performance degredation- like converting an O(N) algorithm into an O(N^2) algorithm.
The classic example of this is lists and arrays. Both data structures have a "get the i-th element" operation, and both can have a "prepend a element" operation. With arrays, the ith operation is O(1), but the prepend operation is O(N) (I have to move all elements of the list out of the way to make room for the new head element). With lists, the ith operation is O(N) (I have to walk down the list), but the prepend operation is O(1). If my algorithm is heavily dependent up getting the ith elemenet, and never or almost never prepends an element, then I want to use arrays and stay far away from lists. If my algorithm prepends elements a lot, and never or rarely, goes and gets the ith element, then I want lists and not arrays. This is exactly the problem the original poster fell into (well, one of them anyways).
Generic implementations of algorithms? Rare, in my experience. Rare to the point that duplicating the code is a legitimate alternative. I mean, consider sorting both lists and arrays. OK, with a little bit of trickery, you could probably write a bubble sort that was (more or less) equally efficient on both lists and arrays. But anything more complicated? OK, let's just limit it to linked lists. For singly linked lists, you basically need to do merge sort. But for doubly linked lists, I've written a variant of heap sort that is twice as fast as merge sort (you treat the next and previous pointers as left and right child pointers, convert the list into a true pointer based heap, and run heap sort on the result).
It's a trade off. I don't see what Ocaml traded off as that valuable- and what Ocaml got in return is strong type checking and type inference. All the benefits of a real type system without the bondage and discipline aspects. All languages are trade offs. If you hold out for having your cake and eating it too, then yes, you will always be dissatisfied.
Having read the article and looked at your Ocaml code, you do have at least one problem in your implementation. You're using lists. Lists are not for random access and modification. To change the nth element of a list, you need to modify (and reallocate) n elements.
Try using a map instead. I'll send you example Ocaml code in a day or two (I'm moving, so I don't have that much free time to fix other people's bugs that I'm not getting paid to fix). Note that this is true in Haskell as well as Ocaml. Haskell may be just a little bit better at hiding the problem with laziness- but it's still a problem!
Now, for the brutal part of the response: that big of a difference in performance almost certain does mean you've messed something up in your implementation. But, instead of saying "Gee- I wonder what I screwed up?" you said "Gee- Ocaml and functional programming must just suck!" That I still fault you for.
We do. In fact, we encourage it. They're called 401K's. Look them up- you can sock away up to 15% of your income, before taxes, for retirement. If that isn't enough, you're free to open up your own IRAs and mutual fund investments, or open up your own stock brokerage account, and invest there for a few dozen dollars a year. If that's too much, you can start investing in DRIP for $5 a month or so. I've never heard of a time in our history when it's been so easy for people to save for their retirement, or have so many ways to do so.
Social Security isn't *investment*, it's *insurance*. It's a gaurentee that you won't have to spend your retirement years under a bridge.
This change will make stock options for anyone except the top most layers of management a thing of the past. You see, stock options are already expensed. The main measure of the value of a company is the Earnings Per Share, or EPS. This is the ratio of the total earnings of the company divided by the number of outstanding shares. Increase the number of shares, and what happens? The EPS drops. But now, if you issue stock options, you get hit twice. You get hit once by falling EPS due to the increased number of shares, and a second time as you have to decrease your earnings by an amount equal to the value of the stock option grant.
The problem with stock options were the immediate grants. The idea behind stock options was to give the people in the company- not just the upper level management, but everyone- a stake in the company. A stake in the long term prospects of the growth- especially if the options you're granted now can't be exercised for five years. All of a sudden not only are you less likely to quit (and lose those options!), you're more concerned about where the company will be five years from now.
The problem is with the CEOs getting multimillion dollar stock grants, on pennies on the dollar, effective immediately. This encourages to pump up next quarter's numbers by any means, hook or crook, so they can dump their stock. And to heck with where the company will be a year, let alone five years from now.
But hey- given a chance to throw the baby out but keep the bathwater, would we pass up the chance?
Brian
And if you think Sun is bad, just wait until Microsoft starts playing with you.
My recommendation: learn Ocaml.
While it does moderately well on this test (finishing near the middle), you might be surprised at it's weak finish compared to it's reputation as a concise language. Well, as a committed Ocaml advocate, Ocaml isn't a scripting language. I freely admit that it has so-so string handling, no built-in regular expressions, so-so process handling, etc. But this is because it isn't a scripting language- it's an applications language, like C++, Java, and C#. And the only reason it does as well as it does is because it's a signifigantly better language than it's competition.
If you're writting a quick script to grep through the log files looking for port scanners, Ocaml is the wrong language.
Brian
Or if they do, they won't last past the first snow. Along comes a snowplow, and *pop* *pop* *pop* there go the reflectors, smart or not, right into the ditch. Along with the odd hunk of concrete that was sticking up, unlucky mailboxes, small cars...
Nice idea for SoCal, tho.
Computers, used correctly, can be a great benefit to education. Take a look at the Teach Scheme project as an example- among other things, they use programming to help teach math. Educators, however, have to get a few things through their heads: 1) They're teaching life skills, not jobs skills. You don't need the latest and greatest of anything. I learned to write using Wordstar 3.0 on an 8086- Word 2 for Windows on a 133 MHz Pentium is enough, you don't need a 3GHz P-4 with Windows XP. Remember that your average 9th grader is still 8 years from entering the work place- so 2004 technology will be as obsolete when they land their first job as 1996 technology is today. And those 3rd graders? They're 14 years away from getting a job- today's technology will be like using 1990 technology. Windows 95 vr.s Windows XP doesn't matter. 2) Everyone needs to be taught to program. This isn't just a class for upper classmen (notice the *men*) looking to go into technical careers. I don't think 2nd or 3rd grade it too early to start teaching everyone to program- this is the point of the Logo language. And the earlier they come to it, the less strange it will be! 3) The computer needs to be used for more than rote memorization drills. This is the number one failure I see. Computers are, first and foremost, problem solving tools. This is why programming is so important- the *child* should be figuring out ways to get the computer to solve problems in the field being taught. With mathematics, this is easy- add a couple of graphics routines, and all of a sudden geometry comes alive. Algebra is all over programming. The computer has fascinating abilities as a musical instrument. Etc. As someone who was originally taught to write with pen on paper, I *hated* writting. One mistake and you had to copy the entire page over. Until I discovered computers. Opps- mispelled that word? Just go back and correct it. Hmm- that paragraph is in the wrong spot, let's move it. Don't worry about the details, get the ideas down and fix it later. This is still how I write (it's how I wrote this posting). And instead of hating writting, I enjoy it. Of course, this requires a lot more computers. Which is why it's important that school systems not buy the latest and greatest (which always cost), but instead can get by on seriously obsolete hardware. Lots of counter examples, of computers incredibly enhancing education, exist. See especially The Children's Machine by Seymore Papert. But notice how these success stories tend to follow my guidelines much more so than "traditional" education does.
It's the falsifiability that makes it usefull for solving problems (curing diseases,etc.). Unlike other Dogmas, science doesn't provide the answers- it only provides the means to find the answers.
An interesting observation is that the theorem "the scientific method is an effective way of understanding the universe" is, itself, a falsifiable theorem, and thus can be investigated scientifically. We can perform experiments and get data telling us wether it's true or not. Actually doing this is left as exercise to the student (hint: consider the historical record).
As I understand the law here in the States (IANAL, etc), being the *unknowning* recipient of stolen property does not make you a criminal, even if you make money off that property. The most that SCO should be able to demand is that certain parts of the kernel be removed. Notice how they're being seriously vague about *what* parts of the kernel are theirs, because otherwise such an effort would already be underway.
The claim that you cannot write a Unix OS without their magic ingredient is pure horsepucky. As any engineer in the industry will tell you. The theory is all out in the open, and little if any of it was developed by SCO.
Brian
Assume you have four euclidean points, A, B, C, and D. A, B, and C are colinear, and B, C, and D are colinear.
Assume D is *not* on the line A-B-C. Therefor, the set of points A, B, and D define a plane- if there is a solution, it is on a single plane. Going into n dimensions doesn't help- if there is a solution, it's planar.
But two points define a line. So the A-B-C line can be defined by two points, B and C say. But so can the B-C-D line, indeed by the same two points! The two lines have to share at least two points, therefor D has to be on the A-B-C line.
The trick is the question talked about *pennies*, not euclidean points. This gives us some fudge room, and the solution *must* take advantage of this fudge room. The only other alternative is to leave euclidean geometery. Anyone got a black hole handy?
Brian
I'm trying to remember all the Unix variations that ran on the x86 before 1998 (when IBM took a major interest in Linux). A partial list is:
m l)
-Solaris x86 (SysV) and SunOs (BSD) (anyone remember the Sun-386?)
- Minix
- Linux
- Several BSDs
- Xinu (same idea as Minix, not as popular a book: see http://public.ise.canberra.edu.au/~chrisc/xinu.ht
- Xenix
- NextStep 386
- Gnu/Hurd
- There was a DOS extender whose name I was forgetting which implemented most of Unix at one point (started with a C?).
There are probably more, but that's all I'm remembering.
Brian
Argh. Plain old text obviously isn't.
The above code should look like:
a < b, c > d;
(a < b), (c > d);
(a < b, c >) d;
a < b, c > d, e, f;
etc. Must remember to preview before posting.
The problem is that C++ requires basically an infinite k to parse context free. For example, consider what the compiler does when it sees a set of tokens like:
a d;
Now, is this:
a) a strange but legal expression parsed
like:
(a ) d;
Both are legal interpretations. The only way you can tell is by looking at the type of a before parsing the rest of the expression. And even this may not help. IIRC, the issue may be undecidable, as template names are in a different "namespace" than variable names (i.e. I can have both a template type and a variable with the same name at the same time.
Note that d being a more complex expression than just a name also allows you to decide. But we're up to a k=7 on the simple case. Make b and c arbitrarily complex expressions themselves, and you can make k need to be arbitrarily large. Or heck, consider:
a d, e, f;
(three new variables d, e, and f, or four different expressions combined with the comma operator?).
And it doesn't matter how infrequent this code construct is. The compiler has to deal with this situation, and situations like it. And deal correctly. C++ simply is not LALR(1) parsable, and likely not really parsable at all. It's a fundamental flaw in the language.
And this does cost. YACC was developed because it's easier to write and maintain parsers in YACC than hand-rolled parsers for any nontrivial but LALR(1) parsable language. Time and effort will go to the development and maintainance of the compilers. For commercial products, this means higher prices. For free products like GCC, this means fewer new features and fewer bugfixes in other parts of the code.
Brian
Unless the functions to inline are *real* small. Think about it- if the function is f bytes in size inlined, and f+a bytes in size as a standalone, and it takes c bytes to call the standalone function, and the function is called in n places, then inlining the function everywhere takes f*n bytes, while calling it takes c*n + f + a bytes. If c f - ((f+a)/n), then it'll be cheaper (require fewer code bytes) to not inline f than to inline f. As n gets large, all you need is c f for it to be a win. How many bytes does it take to call a function? That's your target- if your function is more than a few lines of code (at best) you're probably better off not inlining the function.
I'd actually be inclined to go the other direction- is it possible to uninline things? If the code is doing similiar things in different places, is it possible to write a single function which is instead called in both places?
Barring that, other options include using a different complier- does gcc support your processor? I know gcc doesn't support everything under the sun- many 8- and 16-bit micros and DSPs aren't supported, for example. But if gcc is supported, it does pretty good on the stack space management and automatically inlining. Or you just might have to bite the bullet and spring for a larger rom/flash or larger cpu.
Brian
It's worse than that. The key to decrypt the software is on the disk, just in a "non-standard" location. Obviously, despite it being non-standard the software can read the location. All the cracker has to do is find out where on the disk it is, and read the key off themselves, and viola.
A better example would be the old floppy-based copy protection schemes where they'd use weird track steppings or other floppy controller timings to try and hide the data. If I recall correctly, all the copy protection schemes based on this failed as well. In fact, I seem to remember "perfect copy" programs that would copy said disks anyways. The only thing new here is that they've add cryptography. Not that it helps.
Of course, now I've gone and violated the DMCA. Hmm. Since the information is stored in a "non-standard" location, I wonder if documenting how to access that location aka documenting the hardware interface to the drive is now a DMCA violation?
Brian