a system can't just be put in a closet in a classroom
My old school's building is of very old design, and there are surely many cupboards that nobody knew about, which have not been opened for tens, or maybe even hundreds of years (perhaps an old closet in the boiler room).
Perhaps a closet might be opened during the course of some building works in another hundred years or so. Goodness knows what they might find. Every-so-often I've seen articles in newspapers about old things being perfectly preserved at the back of the cleaners' cupboard, and suchlike.
If the system survives for a few hundred years (even if the electronics does not work), then it could be extremely exciting for the future pupils to see a time bubble in their own school.
If I were organising this, I would be very much in favour of finding an old, ignored, cupboard which hasn't been opened for years, and "preserving" (perhaps just as little as dust covers) a few computers, or mobile phones; and forgetting about them.
Afterthought: I just remembered that in the graphic design building of the school, there was a framed drawing which had been drawn in the nineteenth century by pupils. It had recently been discovered during redecoration work.
It's perhaps worth mentioning that if an inert gas is used, there should be warnings on the packaging. The last thing they want is for a group of students to open the box and drop down dead (from suffocation).
Actually, I just noticed that in the above scenario, git just overwrites the major refactorisation when the local working tree is committed. This is almost certainly not what I'd want:-) I was hoping it would force a merge when I commit the working tree.
I think all in all, pushing to a non-bare repository should probably be discouraged.
Try pushing a change into another Git repository, then navigate to that repository and run "git status" - git does not auto-checkout changes in the destination repository during a push. It's the user's responsibility to detect this and deal with it. I find that design approach - the idea that the user is expected to spot and deal with the internal behaviour of the tool - to be pretty bad.
At first, I found this pretty unintuitive, however, I now feel that automatically checking out the changes would be a Bad Thing(tm).
Most of the time, repositories you push to will be bare repositories, with no working tree. If there is a working tree present, then presumably someone is actively working on it. Imagine you are implementing some new feature in your local copy, which is all very experimental, and perhaps not even compiling yet. Now imagine someone pushes a major refactorisation directly onto your working tree, which does not merge cleanly. I would find this exceedingly annoying. [You have not yet committed any changes, and so the push does merge cleanly with the HEAD, but just not the working tree]
In addition, I think it would be quite distracting if bits of code changed behind my back, when I wasn't expecting it. Especially if I happened to be editing the file in question when it got updated.
The attacker does not need to wait until the response is sent: many can be sent concurrently.
Preventing multiple concurrent login attempts opens the window for DoS attacks.
When my university was allocating individual projects at the start of
the year, I was asked to choose five projects, out of a large set of
available projects. Instead of trying to assign a score to each
individual project, I used quicksort to rank the projects, and then
took the first five items from the head of the list. That way, I only
ever had to choose between two different projects at a time.
It sounds as if this could be better than trying to assign performance
indicators to each employee. Obviously, with 90,000 employees, the
number of comparisons would be rather large; however you could
presumably use a modified sorting algorithm, which accepts a network
of relations (two people are related iff they work together), and sends
a "comparison request" for persons A<=>B to person C, where person C
has worked with both A and B.
The question I was posing wasn't regarding a C implementation, but rather whether the quicksort algorithm's definition includes the partitioning method. On reflection, I suspect you are right, and that an implementation does not need to use in-place partitioning to be considered quicksort.
Hoare's original paper explicitly describes the in-place algorthim, with an alternative for computers which do not have an exchange(ptr, ptr) function (which also seems to compute a new array having only done one iteration of the given array, rather than performing two iterations, as the Haskell algorithm does).
Ah, my apologies, I misinterpreted your original comment. I thought you were talking about the time during the program's execution that a variable is evaluated, rather than the semantics of a variable's value.
Functional variables are like mathematic variables - they're variable in that you may not have discovered their value yet, but once you discover their value it stays the same for the current instance of the problem.
The above is only true for non-strict functional languages. Strict functional languages require the value to be known at the time of binding.
This algorithm does not do in-place partitioning of the array, and so requires two iterations over the array. In addition, it does not use a sensible pivot selection.
To what extent this algorithm can be considered "quicksort" is debatable. I believe the GP is refering to the in-place partitioning varient of quicksort, which requires mutable arrays, or a very clever compiler. Mutable arrays are present in Haskell, but, if I recall correctly, not as efficient as in C (although, they are still O(1) access).
Prelude Data.Function> filter ((>5) `on` snd) [(1,20), (2,3), (3,29)]
:1:8:
Couldn't match expected type `b -> c' against inferred type `Bool'... (snipped)
And also:
fibs = 0 : 1 : (zipWith (+) fibs $ tail fibs)
Which has the advantage of not needing to specify the leading terms in the list, although you could also claim that is a disadvantage (if you prefer fibs 1 1, for example).
Surely a busy-wait infinite loop would be better?
a system can't just be put in a closet in a classroom
My old school's building is of very old design, and there are surely many cupboards that nobody knew about, which have not been opened for tens, or maybe even hundreds of years (perhaps an old closet in the boiler room).
Perhaps a closet might be opened during the course of some building works in another hundred years or so. Goodness knows what they might find. Every-so-often I've seen articles in newspapers about old things being perfectly preserved at the back of the cleaners' cupboard, and suchlike.
If the system survives for a few hundred years (even if the electronics does not work), then it could be extremely exciting for the future pupils to see a time bubble in their own school.
If I were organising this, I would be very much in favour of finding an old, ignored, cupboard which hasn't been opened for years, and "preserving" (perhaps just as little as dust covers) a few computers, or mobile phones; and forgetting about them.
Afterthought: I just remembered that in the graphic design building of the school, there was a framed drawing which had been drawn in the nineteenth century by pupils. It had recently been discovered during redecoration work.
It's perhaps worth mentioning that if an inert gas is used, there should be warnings on the packaging. The last thing they want is for a group of students to open the box and drop down dead (from suffocation).
i will review a random class from time to time to keep it fresh in my mind.
--
-I only code in BASIC.-
If those classes were on BASIC, I would let your mind recover; your penance is over.
Actually, I just noticed that in the above scenario, git just overwrites the major refactorisation when the local working tree is committed. This is almost certainly not what I'd want :-) I was hoping it would force a merge when I commit the working tree.
I think all in all, pushing to a non-bare repository should probably be discouraged.
Try pushing a change into another Git repository, then navigate to that repository and run "git status" - git does not auto-checkout changes in the destination repository during a push. It's the user's responsibility to detect this and deal with it. I find that design approach - the idea that the user is expected to spot and deal with the internal behaviour of the tool - to be pretty bad.
At first, I found this pretty unintuitive, however, I now feel that automatically checking out the changes would be a Bad Thing(tm).
Most of the time, repositories you push to will be bare repositories, with no working tree. If there is a working tree present, then presumably someone is actively working on it. Imagine you are implementing some new feature in your local copy, which is all very experimental, and perhaps not even compiling yet. Now imagine someone pushes a major refactorisation directly onto your working tree, which does not merge cleanly. I would find this exceedingly annoying. [You have not yet committed any changes, and so the push does merge cleanly with the HEAD, but just not the working tree]
In addition, I think it would be quite distracting if bits of code changed behind my back, when I wasn't expecting it. Especially if I happened to be editing the file in question when it got updated.
The attacker does not need to wait until the response is sent: many can be sent concurrently. Preventing multiple concurrent login attempts opens the window for DoS attacks.
When my university was allocating individual projects at the start of the year, I was asked to choose five projects, out of a large set of available projects. Instead of trying to assign a score to each individual project, I used quicksort to rank the projects, and then took the first five items from the head of the list. That way, I only ever had to choose between two different projects at a time.
It sounds as if this could be better than trying to assign performance indicators to each employee. Obviously, with 90,000 employees, the number of comparisons would be rather large; however you could presumably use a modified sorting algorithm, which accepts a network of relations (two people are related iff they work together), and sends a "comparison request" for persons A<=>B to person C, where person C has worked with both A and B.
This is probably far from perfect :-)
The question I was posing wasn't regarding a C implementation, but rather whether the quicksort algorithm's definition includes the partitioning method. On reflection, I suspect you are right, and that an implementation does not need to use in-place partitioning to be considered quicksort. Hoare's original paper explicitly describes the in-place algorthim, with an alternative for computers which do not have an exchange(ptr, ptr) function (which also seems to compute a new array having only done one iteration of the given array, rather than performing two iterations, as the Haskell algorithm does).
Ah, my apologies, I misinterpreted your original comment. I thought you were talking about the time during the program's execution that a variable is evaluated, rather than the semantics of a variable's value.
Also useful is just using par to do a pure evaluation in the background.
a `par` b `seq` (a + b)
Will evaluate a and b in parallel, and then sum them.
Functional variables are like mathematic variables - they're variable in that you may not have discovered their value yet, but once you discover their value it stays the same for the current instance of the problem.
The above is only true for non-strict functional languages. Strict functional languages require the value to be known at the time of binding.
qsort [] = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)
This algorithm does not do in-place partitioning of the array, and so requires two iterations over the array. In addition, it does not use a sensible pivot selection. To what extent this algorithm can be considered "quicksort" is debatable. I believe the GP is refering to the in-place partitioning varient of quicksort, which requires mutable arrays, or a very clever compiler. Mutable arrays are present in Haskell, but, if I recall correctly, not as efficient as in C (although, they are still O(1) access).
Ken Thompson talks about using untrusted compilers in his lecture, "Reflections on Trusting Trust".
(See also: this)
Prelude Data.Function> filter ((>5) . snd) [(1,20), (2,3), (3,29)]
[(1,20),(3,29)]
Rather than:
Prelude Data.Function> filter ((>5) `on` snd) [(1,20), (2,3), (3,29)]
:1:8:
Couldn't match expected type `b -> c' against inferred type `Bool' ... (snipped)
The picture in the linked article is missing a beard.
There is a beard, but you have not evaluated it yet.
fibs x y = x : (fibs y (x + y))
And also:
fibs = 0 : 1 : (zipWith (+) fibs $ tail fibs)
Which has the advantage of not needing to specify the leading terms in the list, although you could also claim that is a disadvantage (if you prefer fibs 1 1, for example).
Aside from the obvious, there are some interesting papers, essential reading, a mailing list, a tutorial, and even a (reasonably complete) wikibook.