We don't really know how long it would take... you and I are used to language and could easily teach it to children. We could probably invent a reasonable language if necessary (Elvish, Klingon etc etc). But if your parents had never spoken a language to you, if the idea of sentences was totally new, it might not be so easy.
This brings to mind the experiment by some English king (IIRC) to lock two newborn infants in the Tower of London, allow them food but no human contact, and see what language they developed. Unfortunately both children died.
To talk to your children you would need to have a language to teach them, of course... this thing could take a long time to get going. But I agree that if the mutated form is dominant then you could get a reasonable clump of people grunting at each other within a few generations.
But if you are the only person to have language, what good does it do you? How can you impress women with your guitar playing skills if they have no appreciation of music?
Biologists do say that the spread of a gene in a population can follow a pattern where it increases slowly for a long time, then passes a threshold and shoots up rapidly to almost the whole population. Perhaps the creativity gene was like that.
The article doesn't discuss how a single mutation would have spread through the population. In prehistoric times what advantage would there be in a gene that makes you carve useless bone trinkets?
Even if there were an advantage in having this gene it could not have suddenly spread through the whole human population. The more artistic humans would have to gradually displace their stupider cousins. And we could expect to see surviving tribes in remote areas still lacking the creativity gene.
Apocalypsen? You can't just stick -en on the end of any word to make a plural, it has to be reasonably Germanic-sounding (like Vaxen, compare hexen). Apocalypse comes from Greek apokalypsis, so the plural has to be apocalpyses, which is correct both by the classical Greek rules (I think) and by the English rule of adding -s.
OK, perhaps the semicolon is unnecessary. The language could use end of line as a statement terminator. Concede that one to Python.
The dollar sign, well it does have its uses, consider string interpolation:
print "The number is $num.\n";
which is not nearly as concise in Python, especially for interpolating a large number of variables into a string. The $ also means that Perl functions can be called without parentheses, as in the example above. In Python, every function call must have () around its arguments, and you could argue this is 'unnecessary' or 'extraneous'. (There is some special case sugar for 'print' in Python but I don't think you can use it for your own functions.) In Perl you have some extra syntax for variables but it allows you to use less syntax for function calls and string interpolation: swings and roundabouts.
The 'my' part is not just extra syntax, it is semantic. It declares the scope of the variable. One of the biggest problems with Python IMHO is the impossibility of specifying the scope of a local variable - I don't know whether this has been fixed in the latest Python releases.
Partly agree about the other stuff, but I think that having two different quote characters mean different things is sensible. You wouldn't argue that C is a broken language because it makes a big difference whether you have () or {} around bits of code.
I'm used to programming in Perl and when using Python the main two annoyances are:
- No decent closures. They say that in Python 2.2 proper closures have been added, but it still doesn't seem possible to construct them, because the 'lambda' operator only allows an expression, not a statement, so you can't do anything non-trivial inside your lambda expression. For example, I often write Perl code passing round functions, eg:
my $count; my $f = sub { ++$count }; my $g = sub { print "hello\n" if $count == 5 };
But there doesn't seem to be any way to construct these closures in Python.
- The other thing I miss is Perl's labelled loop blocks, so that instead of 'next' and 'last' always referring to the inner loop you can say 'next LABEL' and 'last LABEL'. This can often make code more readable and eliminate the need for Pascal-like condition variables and contorted code to check them. Also I think 'next' and 'last' are clearer names than C's 'continue' and 'break', but that's a matter of taste:-).
I too hated that you had to use references to make nested data structures. But I've come to appreciate the fact that the language distinguishes between value semantics and reference semantics. So @a = @b will do a (shallow) value copy, while you can do $a = \@b if you want to take a reference. This is analogous to 'vector' versus 'vector *' in C++. It's nice to have both.
What annoys me is that Perl has no way to just store one list inside another. If I want to make a list of lists, and have value semantics, why can't I just say $a[5] = @b? It might not be that efficient to program this way, just as a vector is not normally that sensible in C++, but it would make things a lot more consistent. You could choose to work with values or with references, instead of being forced into references just to make nested data structures.
I don't know whether perl6 will support this; probably not. It might end up using only references but without the -> operator that reminds you that you are dereferencing something.
S# helps solve some relatively intractable problems. For example, you may declare a parameter of a public method as an object of type String. Within your method, you call the String.IndexOf method. So far so good--but you have to plan for errors. Another programmer is perfectly free to call your method and pass a Null (Nothing, in VB.NET). Despite the fact that Null is not a String, the.NET framework will happily make the call. That means that your method code needs to check for the possibility that someone did in fact pass a Null, and react accordingly. In contrast, in S#, Null is a true object, meaning you can simplify your code by dynamically adding a Null.IndexOf method, and doing nothing. At one fell swoop, you've eliminated both the possibility of an error and all the "if (var == null)" checks you have to write in other languages.
Oh yeah, sure, you've really eliminated the possibility of error. Why not add every method to the 'null' object while you're about it, then your program could _never_ have null-related bugs!
I think it's no longer true that all Tk implementations require Tcl. The very first Tk libraries for other languages used to call the Tcl interpreter, but I think that Perl's Tk and Python's Tkinter now call the C code directly.
It would cost Sony very little to manufacture the laptops the same as any others, then if a customer orders one without Windows to stick in a special boot floppy that wipes the disk clean just before sale. Heck, they could even send you the Windows licence code in a sealed envelope along with the laptop, and if you choose not to pay for Windows they don't send you this piece of paper and the installed Windows version is useless. There is no reason why choosing not to have a particular OS should add any cost to the manufacturing process.
The answer to the dilemma is to set clear limits on the copyright monopoly, particularly *time limits*.
Some have suggested that it's reasonable for the copyright owner to make 90% of the profit. So if the typical book generates 90% of its total profits within the first twenty years of publication, copyright on books should last for twenty years. The 10% reduction in profit for the publisher (compared to perpetual copyright) is more than outweighed by the increased gain to the public from having the book in the public domain after 20 years.
I think the KB-8923 is a membrane keyboard, not buckling spring like the Model M. IBM hasn't made any buckling spring keyboards since they spun off Lexmark, AFAIK. The KB-8923 may be a decent keyboard as membrane/rubberdome units go but it's not in the same league as the Model M or the earlier IBM keyboards.
Factoring a large number provided by the SMTP host is no good - you only need one host which isn't enforcing this and the whole system breaks. If there are open relays now, what are the odds of getting every mail server to switch to the new system?
Factoring a number provided by the _client_ is a better way, that way the clients can decide how high a 'price' they will set, with some demanding at least 10 seconds of CPU time (at current speeds) to deter all spam, while others don't require any 'payment' and choose to accept all messages.
Alternatively, instead of factoring a number provided by the client, you can take a hash of the message body and recipient's address, and do something computationally intensive with that. This proves you have burnt a reasonable number of CPU cycles to send the message, and the result can be checked by the client at the other end. Because the recipient's address is included in the hash you have to recompute for each message you send out.
My reaction to this story is 'well, duh'. If it costs you nothing extra, of course you will choose a route for your traffic without considering the effects on others. It's like the classic analogy of a train seat which has room enough for two: a third passenger coming along is likely to squeeze onto the end of the seat, squashing the other two, because *for him* it is better than standing.
The answer is for routing costs to accurately reflect the contention for resources. If a particular route gets crowded, charge slightly more for sending packets down it. Routers can negotiate in real time to set prices and find the cheapest route for their data. Quality of service guarantees can be implemented by purchasing bandwidth (or options to use bandwidth) in advance.
You won't eliminate selfish behaviour, the way to keep things running smoothly is to make sure people pay for the cost of the resources they use (and no more). Then it will be in their own interests to consider the effect on others, and to avoid overusing already congested routes.
It ought to be possible to have some fast checking of a small number of cache locations: if you can hardcode the defect list on the chip then a small number of gates can say 'yea' or 'nay' to any cache location given to it. It's not like doing some expensive lookup.
Yes, I agree, in a dynamically typed language there is less likely to be a common base class. My point was that _if_ you are programming in a statically typed OO language then the problem of two objects with the same interface but not sharing a base class is unlikely to happen.
If some browsers have bugs in the CSS implementation, it's simple to work around that by just not serving CSS stylesheets to those browsers, or serving an empty stylesheet.
The type system in C is not particularly expressive. In C++ you would be able to declare a linked list of pointers to T, and have this checked, and avoid casting things to (void *) and back again.
In a language with type classes you could write a function to work on any kind of object and again specialize it to the particular types you are using, and have this checked at compile time. In most cases without having to write any explicit type declarations yourself.
Have a look at languages which have type inference and type classes. Type inference means that most of the time, you do not have to declare types for your variables, the compiler will figure it out. For example using the + operator means that both arguments must be some kind of number. You get an error when the compiler infers a clash, such as using + on a variable in one place (which makes it a number) and then doing concatenation on it in another (which means it has to be a list). You can also add type declarations to make your intention clear. Declaring the type of variables is extra information which should not be necessary, but because programmers make mistakes, the redundant information can help to track down where the mistake occurs. It's a similar principle to putting assertions in the code, which are redundant properties checked at run time.
(This point is so important I feel like repeating it. Adding lines of code does not cause errors - not if those lines are extra checking to catch errors that might have crept in elsewhere.)
Your add_int() and add_float() example would be dealt with by type classes. For example in Haskell the (+) function has the type
Num t => t -> t -> t
which roughly means that it takes two arguments of type t and gives back a result of type t. But t must be an instance of 'Num'.
In object-oriented languages like C++ or Java you would do the same with a base class of 'things that can be added'. Not with this trivial example, of course, since you have the builtin types and + operator from C, but for things like 'Printable' or 'Serializable'.
Or with overloading you can define a foo() function taking an int and another taking a float or any other object you want. You'll be told at compile time if a suitable function can't be found for the types you are using.
You make a good point about writing to a particular interface, and looking at the set of messages an object understands. You can get this by having a common abstract base class or interface. I don't think the example of 'two objects in two hierarchies that understand a common set of messages' is particularly likely to happen in practice, because in a statically typed OO language these objects would be written to have a common base class. However, there might be a type system that keeps track of the messages that can be received by an object, and checks that at compile time. ('You are trying to call method foo() on variable a, but this variable might be of type X, which does not have a foo() method.')
We don't really know how long it would take... you and I are used to language and could easily teach it to children. We could probably invent a reasonable language if necessary (Elvish, Klingon etc etc). But if your parents had never spoken a language to you, if the idea of sentences was totally new, it might not be so easy.
This brings to mind the experiment by some English king (IIRC) to lock two newborn infants in the Tower of London, allow them food but no human contact, and see what language they developed. Unfortunately both children died.
To talk to your children you would need to have a language to teach them, of course... this thing could take a long time to get going. But I agree that if the mutated form is dominant then you could get a reasonable clump of people grunting at each other within a few generations.
But if you are the only person to have language, what good does it do you? How can you impress women with your guitar playing skills if they have no appreciation of music?
Biologists do say that the spread of a gene in a population can follow a pattern where it increases slowly for a long time, then passes a threshold and shoots up rapidly to almost the whole population. Perhaps the creativity gene was like that.
The article doesn't discuss how a single mutation would have spread through the population. In prehistoric times what advantage would there be in a gene that makes you carve useless bone trinkets?
Even if there were an advantage in having this gene it could not have suddenly spread through the whole human population. The more artistic humans would have to gradually displace their stupider cousins. And we could expect to see surviving tribes in remote areas still lacking the creativity gene.
Er, so how would you propose declaring local variables? What keyword would you use?
Or do you think that variables should not need any declaration? If so, how does the language decide what the scope of the variable should be?
Apocalypsen? You can't just stick -en on the end of any word to make a plural, it has to be reasonably Germanic-sounding (like Vaxen, compare hexen). Apocalypse comes from Greek apokalypsis, so the plural has to be apocalpyses, which is correct both by the classical Greek rules (I think) and by the English rule of adding -s.
[unnecessary syntax in 'my $num = 1;']
OK, perhaps the semicolon is unnecessary. The language could use end of line as a statement terminator. Concede that one to Python.
The dollar sign, well it does have its uses, consider string interpolation:
print "The number is $num.\n";
which is not nearly as concise in Python, especially for interpolating a large number of variables into a string. The $ also means that Perl functions can be called without parentheses, as in the example above. In Python, every function call must have () around its arguments, and you could argue this is 'unnecessary' or 'extraneous'. (There is some special case sugar for 'print' in Python but I don't think you can use it for your own functions.) In Perl you have some extra syntax for variables but it allows you to use less syntax for function calls and string interpolation: swings and roundabouts.
The 'my' part is not just extra syntax, it is semantic. It declares the scope of the variable. One of the biggest problems with Python IMHO is the impossibility of specifying the scope of a local variable - I don't know whether this has been fixed in the latest Python releases.
Partly agree about the other stuff, but I think that having two different quote characters mean different things is sensible. You wouldn't argue that C is a broken language because it makes a big difference whether you have () or {} around bits of code.
I'm used to programming in Perl and when using Python the main two annoyances are:
:-).
- No decent closures. They say that in Python 2.2 proper closures have been added, but it still doesn't seem possible to construct them, because the 'lambda' operator only allows an expression, not a statement, so you can't do anything non-trivial inside your lambda expression. For example, I often write Perl code passing round functions, eg:
my $count;
my $f = sub { ++$count };
my $g = sub { print "hello\n" if $count == 5 };
But there doesn't seem to be any way to construct these closures in Python.
- The other thing I miss is Perl's labelled loop blocks, so that instead of 'next' and 'last' always referring to the inner loop you can say 'next LABEL' and 'last LABEL'. This can often make code more readable and eliminate the need for Pascal-like condition variables and contorted code to check them. Also I think 'next' and 'last' are clearer names than C's 'continue' and 'break', but that's a matter of taste
I too hated that you had to use references to make nested data structures. But I've come to appreciate the fact that the language distinguishes between value semantics and reference semantics. So @a = @b will do a (shallow) value copy, while you can do $a = \@b if you want to take a reference. This is analogous to 'vector' versus 'vector *' in C++. It's nice to have both.
What annoys me is that Perl has no way to just store one list inside another. If I want to make a list of lists, and have value semantics, why can't I just say $a[5] = @b? It might not be that efficient to program this way, just as a vector is not normally that sensible in C++, but it would make things a lot more consistent. You could choose to work with values or with references, instead of being forced into references just to make nested data structures.
I don't know whether perl6 will support this; probably not. It might end up using only references but without the -> operator that reminds you that you are dereferencing something.
Oh yeah, sure, you've really eliminated the possibility of error. Why not add every method to the 'null' object while you're about it, then your program could _never_ have null-related bugs!
I think it's no longer true that all Tk implementations require Tcl. The very first Tk libraries for other languages used to call the Tcl interpreter, but I think that Perl's Tk and Python's Tkinter now call the C code directly.
No, I think the reason why certain optimizations are not available in gcc is due to software patents in some countries.
It would cost Sony very little to manufacture the laptops the same as any others, then if a customer orders one without Windows to stick in a special boot floppy that wipes the disk clean just before sale. Heck, they could even send you the Windows licence code in a sealed envelope along with the laptop, and if you choose not to pay for Windows they don't send you this piece of paper and the installed Windows version is useless. There is no reason why choosing not to have a particular OS should add any cost to the manufacturing process.
The answer to the dilemma is to set clear limits on the copyright monopoly, particularly *time limits*.
Some have suggested that it's reasonable for the copyright owner to make 90% of the profit. So if the typical book generates 90% of its total profits within the first twenty years of publication, copyright on books should last for twenty years. The 10% reduction in profit for the publisher (compared to perpetual copyright) is more than outweighed by the increased gain to the public from having the book in the public domain after 20 years.
It's all because God doesn't keep up with the new vulnerabilities and release patches to human DNA.
So their new section will be called Bloggle?
I think the KB-8923 is a membrane keyboard, not buckling spring like the Model M. IBM hasn't made any buckling spring keyboards since they spun off Lexmark, AFAIK. The KB-8923 may be a decent keyboard as membrane/rubberdome units go but it's not in the same league as the Model M or the earlier IBM keyboards.
Factoring a large number provided by the SMTP host is no good - you only need one host which isn't enforcing this and the whole system breaks. If there are open relays now, what are the odds of getting every mail server to switch to the new system?
Factoring a number provided by the _client_ is a better way, that way the clients can decide how high a 'price' they will set, with some demanding at least 10 seconds of CPU time (at current speeds) to deter all spam, while others don't require any 'payment' and choose to accept all messages.
Alternatively, instead of factoring a number provided by the client, you can take a hash of the message body and recipient's address, and do something computationally intensive with that. This proves you have burnt a reasonable number of CPU cycles to send the message, and the result can be checked by the client at the other end. Because the recipient's address is included in the hash you have to recompute for each message you send out.
The idea of using CPU cycles as payment is not new, check out Hash Cash.
My reaction to this story is 'well, duh'. If it costs you nothing extra, of course you will choose a route for your traffic without considering the effects on others. It's like the classic analogy of a train seat which has room enough for two: a third passenger coming along is likely to squeeze onto the end of the seat, squashing the other two, because *for him* it is better than standing.
The answer is for routing costs to accurately reflect the contention for resources. If a particular route gets crowded, charge slightly more for sending packets down it. Routers can negotiate in real time to set prices and find the cheapest route for their data. Quality of service guarantees can be implemented by purchasing bandwidth (or options to use bandwidth) in advance.
You won't eliminate selfish behaviour, the way to keep things running smoothly is to make sure people pay for the cost of the resources they use (and no more). Then it will be in their own interests to consider the effect on others, and to avoid overusing already congested routes.
It ought to be possible to have some fast checking of a small number of cache locations: if you can hardcode the defect list on the chip then a small number of gates can say 'yea' or 'nay' to any cache location given to it. It's not like doing some expensive lookup.
Yes, I agree, in a dynamically typed language there is less likely to be a common base class. My point was that _if_ you are programming in a statically typed OO language then the problem of two objects with the same interface but not sharing a base class is unlikely to happen.
If some browsers have bugs in the CSS implementation, it's simple to work around that by just not serving CSS stylesheets to those browsers, or serving an empty stylesheet.
The type system in C is not particularly expressive. In C++ you would be able to declare a linked list of pointers to T, and have this checked, and avoid casting things to (void *) and back again.
In a language with type classes you could write a function to work on any kind of object and again specialize it to the particular types you are using, and have this checked at compile time. In most cases without having to write any explicit type declarations yourself.
Have a look at languages which have type inference and type classes. Type inference means that most of the time, you do not have to declare types for your variables, the compiler will figure it out. For example using the + operator means that both arguments must be some kind of number. You get an error when the compiler infers a clash, such as using + on a variable in one place (which makes it a number) and then doing concatenation on it in another (which means it has to be a list). You can also add type declarations to make your intention clear. Declaring the type of variables is extra information which should not be necessary, but because programmers make mistakes, the redundant information can help to track down where the mistake occurs. It's a similar principle to putting assertions in the code, which are redundant properties checked at run time.
(This point is so important I feel like repeating it. Adding lines of code does not cause errors - not if those lines are extra checking to catch errors that might have crept in elsewhere.)
Your add_int() and add_float() example would be dealt with by type classes. For example in Haskell the (+) function has the type
Num t => t -> t -> t
which roughly means that it takes two arguments of type t and gives back a result of type t. But t must be an instance of 'Num'.
In object-oriented languages like C++ or Java you would do the same with a base class of 'things that can be added'. Not with this trivial example, of course, since you have the builtin types and + operator from C, but for things like 'Printable' or 'Serializable'.
Or with overloading you can define a foo() function taking an int and another taking a float or any other object you want. You'll be told at compile time if a suitable function can't be found for the types you are using.
You make a good point about writing to a particular interface, and looking at the set of messages an object understands. You can get this by having a common abstract base class or interface. I don't think the example of 'two objects in two hierarchies that understand a common set of messages' is particularly likely to happen in practice, because in a statically typed OO language these objects would be written to have a common base class. However, there might be a type system that keeps track of the messages that can be received by an object, and checks that at compile time. ('You are trying to call method foo() on variable a, but this variable might be of type X, which does not have a foo() method.')