I don't see how this contradicts the innate ability to learn language theory that Chomsky put forth.
Chomsky is repeatedly on the record saying that general-purpose statistical methods are not sufficient to learn a language.
The significance of this phenomenon in the greater scheme of automatic syntactic parsing?
None at all.
On the other hand, if one happens to care about the minute details of insane Chomskian syntactic theory, then it matters enormously, because insane Chomskian syntactic theorists are forbidden from just stating the rule as-is in their theory. I mean, it justdoesn't sound impressive enough. They're supposed to derive it as some sort of complicated "theorem" from deep principles of Universal Grammar, and thus, to gloriously prove to the world that Plato was right about innate ideas.
Did I just say "gloriously prove to the world that Plato was right about innate ideas"? My apologies. I meant "gloriously prove that Chomsky is right about Plato being right about innate ideas."
(People reading this might guess that if you're simply trying to state the rules of the grammar of the language, without any ulterior Chomskian motives, you might not really think that do-support is a specially thorny problem...)
Aboriginal tribesmen somehow sensed the impending danger of December's tsunami in time to flee to higher ground before the first sign of water.
It just stating (and this is in TFA) that not all the patterns we recognize we're aware of.
But according to all credible reports, the people in question consciously noticed that the sea had receded significantly, and consciously recalled stories passed down about what happens after that.
Though I've done it at a higher level of the educational system (while doing a Ph.D. in Linguistics). The big, big advantage of using search engines is the sheer size and variety of the content available on the web. For a number of things, there is simply no other way to get enough examples, because the phenomenon you're interested in is just too rare.
The downsides are repetitiveness (it's often the case that you get the same document a lot of times at many different URLs; for example, song lyrics), typos, unreliable language-dectection algorithms in search engines (search for weird stuff in Spanish in Google, and you'll often get back some Portuguese results), unreliable numbers, etc.
Contrary to what you're assuming, the people in question do not propose that NULL should be comparable to non-NULL values in SQL. What they propose is doing away completely with SQL's NULL semantics, and putting something substantially different in place (or maybe even nothing).
In practice, NULL is used to mean two things, and it's often not clear in an individual instance which it is:
We don't know what the value for that field should be (or whether there is one).
We know that there is no value for that field.
The first of these is "the database has no information for this field", the second is "the database has the information that there's no value for that field". I've seen a fair amount of confusion in cases where it's not clear which of these a NULL stands for in one case.
What should I do to indicate that I have no adress anylonger? I can not call delete and I can not tell GC, hey come on, GC, please remove my address. IK set my adress to null, and the GC eventually will collect the adress object.
First of all, your class should store the address in a private instance variable, and external access to its values should be through getter and setter methods. It's in general a bad idea to allow the state of a class to be modified by code not in that class.
Second, there is a difference of meaning between setting a field to null because you're using null to mean "no value", and setting it to null because you are trying to cause a garbage collection. The logic to your code there should be "I'm setting this person's address to null because they don't have an address anymore", not "I'm setting the field to null because I want this obejct to be GC'ed."
Third, I think that's an abuse of null anyway. You want to something more abstract, e.g., have a constant Address.NO_ADDRESS assigned to a specially designated instance of the class, that's used to signal the condition where a person has no address. Why? Because you can catch more bugs this way. If you have code elsewhere that does person.getPostalAddress().foo(), and person has a null postalAddress, you're going to get a NullPointerException; if you've assigned a designated instance of Address, then you can control what code gets called.
In general, the problem with null is that when a field is set to null, it can be either because nobody ever set it, or because somebody explicitly set it to null, and it's pretty hard for a program to distinguish these cases.
I am not talking about GC, I am talking about GC implementations. At a very high level, it all looks pretty, but in the real world somewhere a malloc is still called, somewhere a free is still called.
Nope. That's where copying collectors win-- no calls to malloc and free.
Presto, each object in the list references the next, therefore none have a 0 ref count and will be ignored by the garbage collector.
One algorithm to do GC is to go through every reference in your call stack, follow each of them, mark the object you reach as used, do the same for each reference in those objects, and so on (taking care to check for already-marked objects, so as not to fall into cycles). Then, you go through all the heap, and free all the objects you didn't mark.
This algorithm will successfully collect the circular list. I don't think Java uses this one algorithm, but the algorithms it does use will collect the cyclic structures just as well.
Ah yes, nothing says efficiency like periodically examining every single object held in memory (well, every single non-garbage collectable).
You should stop and actually analyze the cost of doing this. Examining an object takes a constant amount of time, so the total cost of a GC cycle is distributed over the number of objects that are allocated. That is, you're only incurring a small constant cost per each object for the mark & sweep cycle, plus whatever your malloc() and free() operations cost.
Sure, manual memory allocation doesn't incur this extra cost, and thus is faster than mark & sweep; but the dominant cost in both cases is that of malloc'ing and freeing objects (maintaining free lists, and in general, dealing with memory fragmentation). Stop-and-copy GC avoids this cost, but at the expense of using more memory than manual allocation or mark & sweep.
Sure, maybe it only happens when you run out of memory,
That's not necessary at all. The mark & sweep algorithm needs to visit every object created during the lifetime of the program, spending a constant amount of time on each to determine liveness. This can be done in a small number of infrequent cycles over a large number of objects, or it can be done over a large number of frequent cycles over smaller sets of objects. The former minimizes the constant overhead incurred by each cycle, and the latter minimizes the amount of garbage in memory at any time; the question is how to strike a good balance.
I don't care about garbage collection, because I know it will never be as efficient as well-managed memory.
What you claim to know right there is demonstrably false. It all depends on object allocation patterns, but it's easy to see that for some such patterns, stop-and-copy garbage collection is faster than manual memory management. With manual memory management, for every object you create, you must do an expensive memory allocation and a deallocation, also expensive. With stop-and-copy GC, you must allocate each object (expensive), copy it at GC time if it's live (cheap), but deallocation comes for free.
The fact is that this is a memory/speed tradeoff. Stop-and-copy is faster in general, but needs more memory (twice as much in the worst-case scenario); manual allocation is slower, but doesn't need as much memory.
This could be fixed by inserting "hugeObject = null" right before while(true){...}.
There is a much more appropriate fix. You see, the code that you wrote there is doing *two* different, relatively unrelated things. This means it should be split up into more than one method. In particular, just refactor the code that deals with hugeObject into a separate method: when the method returns, the reference is destroyed automatically.
"Functions should be short and do just one thing" is a very common principle that's pushed in the name of style, but in a garbage-collected language, it's more than just that: it's a way of implicitly managing memory.
IMO if you find yourself saying this, you are probably doing something wrong.
The trick in a GC'ed language is to manage the lifetime of objects implicitly, by letting references go out of scope. If your x up there is a local variable, you should just return from whichever method you're in. What this means is that people who don't factor their code into simple, short methods that do just one simple thing, tend to keep live references for too long.
If it's an instance variable (and it better be a private one!), then there's two ways of managing the lifetime of the object in question: either the object that keeps the reference does it explicitly, or, you reduce it to the previous technique, applied to the object that keeps the reference.
All it takes is one pointer *ahem* reference to some object that contanis a reference to another, that contains an array... If you've got a few hashes and arrays in the way, it may be difficult to tell exactly where memory is being used, thus memory leaks.
This sounds like bad design and implementation skills to me. And by that I don't mean that people should have some sort of super-human capability to keep mental track of what objects are referenced in the environment; rather, I mean that people should think about collection in terms of protocols like stacks, queues, heaps, etc., which enforce discipline on when their elements are accessed, thus implicitly manage the lifespan of collection members.
Java is both statically and dynamically typed. Every identifier in a source program must have a type, and all objects and methods carry type information that's checked at runtime.
The deal is that the Java static type system is not powerful enough to figure out when an identifier that's declared as type A is bound to an object of a subclass of A. This is where casts enter into the picture; in this case, dynamic typing ensures that casting does not break strong typing.
If you violate type rules in Java, you get (at worst) a well-defined runtime error.
That doesn't sound very static to me.
A good informal definition of strong typing (note I did not say "static") is that all type errors are caught. A language with a strong static type system catches all type errors at compilation time; a language with a strong dynamic type system catches them at runtime.
In C and C++, many type errors are caught at compilation time, but many programs with type errors are accepted by correct implementations, and no mechanism catches them at runtime. Thus, they are weak static languages.
Java is strongly typed, and has both static and dynamic typing. The compiler catches many type errors, and the runtime system catches every other type error.
Nobody needs that much resolution for photojournalism. The Nikon D2H is a really popular photojournalist's DSLR (released last year, and it has had a WiFi expansion card available that long, too). It does 6MP, which experience has shown to be more than adequate. (It also costs half as much as this Canon camera.)
The Nikon D2H, IIRC, shoots 8 or 9 full resolution pictures per second, and has a burst buffer of 40 images. This is way more important for a photojournalist than 16MP.
The summary of these points is that, for this application, it's a better use of bandwidth to transmit more "good enough" pictures than fewer amazingly high-res pictures.
Maybe the code in the Qt/Ruby tutorial linked indirectly from this article (through this page) isn't representative of the bindings. But if it is, I will be terribly disappointed.
One of the best features of Ruby is code blocks. I've skimmed through maybe half of that tutorial, and there are no code blocks in sight.
Now you may wonder why should anybody care about this. Well, simple: there are many, many ways of using Ruby's blocks to make code easier to understand. In the case of a GUI toolkit, I can think of two offhand:
Callbacks. The quickest, simple way to implement a callback is to pass a block as a closure to the widget at construction time.
Representing the embedding of GUI components inside one another. The tutorial code as written works by assigning a variable to a newly instantiated container, then creating contained pieces and including them inside the container by calling methods on the previously created container. All of the pieces occur in the same level of indentation, and the formatting does not make obvious the containment hierarchy of components.
Creating contained components in a code block passed to the container is no harder at all; in Ruby, just make the container's constructor yield self to its block. And what you gain is much nicer than what most people will give credit for: the code that creates the contained elements is visibly "inside" the code that creates the container. Once you're attuned to this convention, it becomes easier to see the structure of the GUI and the code from the indentation in the source.
The vast majority (meaning just about everything) of applications (those not directly interfacing with the kernel in some way) moved absolutely seemlessly from 2.4 to 2.6.
If that's the best example you can come up with, that's far from impressive. Compare to FreeBSD, where you can install compatibility libraries to support software built for any version back to 1.x. That's over 10 years ago.
You really ought to try FreeBSD. Though I doubt the laptop support will be any better than Linux, but, to tell you the truth, if you want a Unixy laptop, a Mac is the answer. (They're not flawless by any means, but they will give you far less trouble than a Linux one.)
I don't see how this contradicts the innate ability to learn language theory that Chomsky put forth. Chomsky is repeatedly on the record saying that general-purpose statistical methods are not sufficient to learn a language.
None at all.
On the other hand, if one happens to care about the minute details of insane Chomskian syntactic theory, then it matters enormously, because insane Chomskian syntactic theorists are forbidden from just stating the rule as-is in their theory. I mean, it justdoesn't sound impressive enough. They're supposed to derive it as some sort of complicated "theorem" from deep principles of Universal Grammar, and thus, to gloriously prove to the world that Plato was right about innate ideas.
Did I just say "gloriously prove to the world that Plato was right about innate ideas"? My apologies. I meant "gloriously prove that Chomsky is right about Plato being right about innate ideas."
(People reading this might guess that if you're simply trying to state the rules of the grammar of the language, without any ulterior Chomskian motives, you might not really think that do-support is a specially thorny problem...)
What if Think Secret lies?
The part you did not quote, of course:
It just stating (and this is in TFA) that not all the patterns we recognize we're aware of. But according to all credible reports, the people in question consciously noticed that the sea had receded significantly, and consciously recalled stories passed down about what happens after that.
Though I've done it at a higher level of the educational system (while doing a Ph.D. in Linguistics). The big, big advantage of using search engines is the sheer size and variety of the content available on the web. For a number of things, there is simply no other way to get enough examples, because the phenomenon you're interested in is just too rare. The downsides are repetitiveness (it's often the case that you get the same document a lot of times at many different URLs; for example, song lyrics), typos, unreliable language-dectection algorithms in search engines (search for weird stuff in Spanish in Google, and you'll often get back some Portuguese results), unreliable numbers, etc.
Isn't revelling in technological advances one way those who are debilitatingly incompetent at relating to people avoid having to face up to that?
*sigh*
There is no misrepresentation or misunderstanding at all. This is *exactly* what the strawman is that you've set up.
Contrary to what you're assuming, the people in question do not propose that NULL should be comparable to non-NULL values in SQL. What they propose is doing away completely with SQL's NULL semantics, and putting something substantially different in place (or maybe even nothing).
HaskellDB
SchemeQL
- We don't know what the value for that field should be (or whether there is one).
- We know that there is no value for that field.
The first of these is "the database has no information for this field", the second is "the database has the information that there's no value for that field". I've seen a fair amount of confusion in cases where it's not clear which of these a NULL stands for in one case.First of all, your class should store the address in a private instance variable, and external access to its values should be through getter and setter methods. It's in general a bad idea to allow the state of a class to be modified by code not in that class.
Second, there is a difference of meaning between setting a field to null because you're using null to mean "no value", and setting it to null because you are trying to cause a garbage collection. The logic to your code there should be "I'm setting this person's address to null because they don't have an address anymore", not "I'm setting the field to null because I want this obejct to be GC'ed."
Third, I think that's an abuse of null anyway. You want to something more abstract, e.g., have a constant Address.NO_ADDRESS assigned to a specially designated instance of the class, that's used to signal the condition where a person has no address. Why? Because you can catch more bugs this way. If you have code elsewhere that does person.getPostalAddress().foo(), and person has a null postalAddress, you're going to get a NullPointerException; if you've assigned a designated instance of Address, then you can control what code gets called.
In general, the problem with null is that when a field is set to null, it can be either because nobody ever set it, or because somebody explicitly set it to null, and it's pretty hard for a program to distinguish these cases.
Nope. That's where copying collectors win-- no calls to malloc and free.
One algorithm to do GC is to go through every reference in your call stack, follow each of them, mark the object you reach as used, do the same for each reference in those objects, and so on (taking care to check for already-marked objects, so as not to fall into cycles). Then, you go through all the heap, and free all the objects you didn't mark.
This algorithm will successfully collect the circular list. I don't think Java uses this one algorithm, but the algorithms it does use will collect the cyclic structures just as well.
You should stop and actually analyze the cost of doing this. Examining an object takes a constant amount of time, so the total cost of a GC cycle is distributed over the number of objects that are allocated. That is, you're only incurring a small constant cost per each object for the mark & sweep cycle, plus whatever your malloc() and free() operations cost.
Sure, manual memory allocation doesn't incur this extra cost, and thus is faster than mark & sweep; but the dominant cost in both cases is that of malloc'ing and freeing objects (maintaining free lists, and in general, dealing with memory fragmentation). Stop-and-copy GC avoids this cost, but at the expense of using more memory than manual allocation or mark & sweep.
Sure, maybe it only happens when you run out of memory,
That's not necessary at all. The mark & sweep algorithm needs to visit every object created during the lifetime of the program, spending a constant amount of time on each to determine liveness. This can be done in a small number of infrequent cycles over a large number of objects, or it can be done over a large number of frequent cycles over smaller sets of objects. The former minimizes the constant overhead incurred by each cycle, and the latter minimizes the amount of garbage in memory at any time; the question is how to strike a good balance.
What you claim to know right there is demonstrably false. It all depends on object allocation patterns, but it's easy to see that for some such patterns, stop-and-copy garbage collection is faster than manual memory management. With manual memory management, for every object you create, you must do an expensive memory allocation and a deallocation, also expensive. With stop-and-copy GC, you must allocate each object (expensive), copy it at GC time if it's live (cheap), but deallocation comes for free.
The fact is that this is a memory/speed tradeoff. Stop-and-copy is faster in general, but needs more memory (twice as much in the worst-case scenario); manual allocation is slower, but doesn't need as much memory.
There is a much more appropriate fix. You see, the code that you wrote there is doing *two* different, relatively unrelated things. This means it should be split up into more than one method. In particular, just refactor the code that deals with hugeObject into a separate method: when the method returns, the reference is destroyed automatically.
"Functions should be short and do just one thing" is a very common principle that's pushed in the name of style, but in a garbage-collected language, it's more than just that: it's a way of implicitly managing memory.
IMO if you find yourself saying this, you are probably doing something wrong.
The trick in a GC'ed language is to manage the lifetime of objects implicitly, by letting references go out of scope. If your x up there is a local variable, you should just return from whichever method you're in. What this means is that people who don't factor their code into simple, short methods that do just one simple thing, tend to keep live references for too long.
If it's an instance variable (and it better be a private one!), then there's two ways of managing the lifetime of the object in question: either the object that keeps the reference does it explicitly, or, you reduce it to the previous technique, applied to the object that keeps the reference.
This sounds like bad design and implementation skills to me. And by that I don't mean that people should have some sort of super-human capability to keep mental track of what objects are referenced in the environment; rather, I mean that people should think about collection in terms of protocols like stacks, queues, heaps, etc., which enforce discipline on when their elements are accessed, thus implicitly manage the lifespan of collection members.
The deal is that the Java static type system is not powerful enough to figure out when an identifier that's declared as type A is bound to an object of a subclass of A. This is where casts enter into the picture; in this case, dynamic typing ensures that casting does not break strong typing.
A good informal definition of strong typing (note I did not say "static") is that all type errors are caught. A language with a strong static type system catches all type errors at compilation time; a language with a strong dynamic type system catches them at runtime.
In C and C++, many type errors are caught at compilation time, but many programs with type errors are accepted by correct implementations, and no mechanism catches them at runtime. Thus, they are weak static languages.
Java is strongly typed, and has both static and dynamic typing. The compiler catches many type errors, and the runtime system catches every other type error.
- Nobody needs that much resolution for photojournalism. The Nikon D2H is a really popular photojournalist's DSLR (released last year, and it has had a WiFi expansion card available that long, too). It does 6MP, which experience has shown to be more than adequate. (It also costs half as much as this Canon camera.)
- The Nikon D2H, IIRC, shoots 8 or 9 full resolution pictures per second, and has a burst buffer of 40 images. This is way more important for a photojournalist than 16MP.
The summary of these points is that, for this application, it's a better use of bandwidth to transmit more "good enough" pictures than fewer amazingly high-res pictures.One of the best features of Ruby is code blocks. I've skimmed through maybe half of that tutorial, and there are no code blocks in sight.
Now you may wonder why should anybody care about this. Well, simple: there are many, many ways of using Ruby's blocks to make code easier to understand. In the case of a GUI toolkit, I can think of two offhand:
Creating contained components in a code block passed to the container is no harder at all; in Ruby, just make the container's constructor yield self to its block. And what you gain is much nicer than what most people will give credit for: the code that creates the contained elements is visibly "inside" the code that creates the container. Once you're attuned to this convention, it becomes easier to see the structure of the GUI and the code from the indentation in the source.
Render what he said in a non-"trollish" way.
If that's the best example you can come up with, that's far from impressive. Compare to FreeBSD, where you can install compatibility libraries to support software built for any version back to 1.x. That's over 10 years ago.
You really ought to try FreeBSD. Though I doubt the laptop support will be any better than Linux, but, to tell you the truth, if you want a Unixy laptop, a Mac is the answer. (They're not flawless by any means, but they will give you far less trouble than a Linux one.)