That day would also spell the end of the web. Most sites exist because of ad revenue, you know.
Adblock does not, by default block Google text ads that appear alongside search results. Nor do I have any desire to block them, because they are often useful and relevant.
The problem isn't with ads. The problem is the low signal-to-noise ratio for most online ads.
While I agree with that at some level, I would say there are too many people that have not explored the full range of what Java itself can do and how techniques learned in different languages can be applied using a combination of Java and various libraries.
Some time ago, I had the problem of exporting a tree of database tables into an XML output file. My solution using C# 1.0 was rather unsatisfactory, and in my spare time I attempted to rewrite the core logic in Haskell. Part of this solution was the two-line function below, which transforms a generic grid of data (with each column representing a successive layer of branches) into a list of trees.
I was unable to come up with anything as neat as this in C#, and I can think of no particular feature of Java that would make it any easier in that language. I'd be interested in any solutions in Java that come close to the conciseness of the Haskell code.
And "favoring different kinds of abstractions" is mostly BS. I've written object-oriented code in assembler! It's just a paradigm, and the only thing a language can help you with is syntactic sugar.
I strongly disagree. There are many abstractions commonly used in other languages that are rarely, if ever, used in Java. For instance, Lisp programmers commonly write macros to transform the structure of their code, whilst in Java, it is extremely rare for a library or framework to delve into bytecode manipulation.
Similarly, a common abstraction in Haskell is the monad. To my knowledge, there are no libraries or frameworks that use this abstraction in Java. Again, this may lead one to ask why is such a common and presumably useful abstraction missing from everyone's Java code.
The problem is that Java doesn't handle these abstractions particularly well. In Lisp, code is defined in terms of lists within lists, and this basic syntax makes it very easy to manipulate. Java's syntax is obviously far more complex, and the compiled bytecode bears little resemblance to the original Java, making byte manipulation a very complex operation.
Likewise, Java's primitive type system makes monads a difficult concept to implement at best. A single line of Haskell loses much of it's clarity when reduced to a page of anonymous classes and interfaces, heaped together in a morbid parody of Church's lambda calculus.
I haven't found any complete implementations of monads in Java, so I can only speculate at what the eventual monstrosity would look like. For comparison, we can refer to a simpler construct, the Y-combinator. In Haskell, it can be defined in one line:
Now, I'm not claiming that it always takes a page of Java and the google-collections library to implement the equivalent functionality of 13 bytes of Haskell. This is obviously an extreme example. However, hopefully it demonstrates my point that there are some forms of abstraction that Java does not take at all kindly to. In this case, lazy evaluation and first class functions.
Like what? Name anything and Java probably already has a library for it. Java is just as flexible as anything these days, and wether your thing in running Ruby on Rails on top of the VM with some Java through in the backend or some functional Groovy work Java has options.
I think you misunderstand me. I'm not criticizing Java's libraries or the JVM. I'm criticizing the Java language.
As for how its limited, just consider the tools used in other languages. Lisp programmers often use macros in their code, because manipulating Lisp code is extremely easy. Java programmers have libraries for generating bytecode on the fly, but they have nowhere near the ease at which S-expressions can be thrown around. As such, libraries or frameworks written in Java that use bytecode generation are relatively rare. In the Lisp world, you'd be hard pressed to find a library that doesn't use macros somewhere.
Similarly, Ruby makes a big deal out of blocks. Java can do similar things with anonymous objects, but again, they're very unwieldy and are not used with the same ubiquity as Ruby uses blocks. Ruby can also add methods to classes on the fly; Java can do this too, via bytecode manipulation, but it's horribly complex compared to Ruby, and thus hardly use.
Another example of a abstraction you don't find in Java is the monad. Used all the time in Haskell, I've never seen a Java implementation. Again, this is because it's so difficult to implement anything that resembles a monad in Java that it's usually not worth the bother.
Note that I'm not complaining about the JVM here. Scala has monads, Groovy has blocks, and Clojure has macros. It's perfectly possible to use these abstractions in the JVM, but usually completely impractical to try using them with the Java language. My criticism, therefore, lies with more with programmers who don't look beyond the language of Java, rather than the VM or standard library that share the same name.
After nearly 20 years of programming experience, I have come to the conclusion that programming languages are totally irrelevant when it comes to "being a master". The real art lies in being able to analyze the problem, and making abstractions to come up with an elegant solution.
The problem with that theory is that different programming languages favour different kinds of abstractions. A programmer only familiar with Java will only be familiar with the abstractions that work well in the Java environment. Compared to some other languages, Java is pretty limited in what abstractions can be practically implemented, so it greatly restricts the amount of solutions available to the programmer.
Page layout is supposed to be its job, and yet it's still very difficult to lay out simple multiple column layouts in CSS with consistent results. Padding and the box model are so byzantine as to confuse even the browser vendors.
I did say that CSS deals with page layout poorly, but it doesn't seem a fundamental failing to me. You could solve it just by adding in better layout controls and deprecating much of the current way CSS handles layout.
I am getting more comfortable with Javascript, though I still think DHTML and CSS are fundamentally fucked, and it really is time, if this web delivery of apps thing is for real, to find some more rational means of actually dealing with dynamic content.
Could you perhaps expand on that? CSS deals with page layout poorly, and it's somewhat badly implemented in IE, but there's nothing I can think of that's fundamentally wrong with it. And I can't think of very much fundamentally wrong with Javascript DOM manipulation, either.
Of course it's not good enough, but improving the situation in any significant fashion would require getting the banks to move away from using passwords and credit card numbers to verify financial transfers, which are far too easy to spoof.
No its not. Because if you condition users to it, they will always accept it, which allows you a trivial downgrade attack to self-signed HTTPS.
Maybe I misunderstood you. I'm not saying we should condition users to dismiss dialog boxes without thinking. I'm saying that the security benefits of having cheap HTTPS outweigh the benefits of refusing self-signed certificates.
The browser should accept all certificates by default without the user having to click anything, but only mark certificates as "secure" if they've been verified by a third party.
And conditioning users to accept self-signed certs for HTTPS is a mistake.
I disagree. A self-signed certificate is better than no encryption at all. I'd just have browsers accept all certificates, but only display the signature yellow address bar and padlock icon for certificates signed by registered third parties.
Using a database gives you fast lookup, consistency checking, locking against race conditions, enforcement of correct structure, dump and load capability, and a standardized interface.
But databases interoperate poorly with version control systems, have no facility for comments, and work best for data that is pretty rigidly structured. Many server applications for Linux have extremely flexible configurations that don't suit the relational database model.
This is probably a good thing. The majority of crimes are committed because the criminal is too stupid to accurately assess risk versus payout. Criminals that make more than the average wage are extremely rare.
I don't really think the trade-off is in static typing and catching errors.
I'm not so sure. JIT compilation can do a lot to mitigate the performance impact of hash-lookups. The author of Psyco, for instance, holds that an expressive language like Python could theoretically run faster than C, because the compiler has access to more information with which to optimize the code.
My experience with Clojure seems to bear out this claim. Clojure is a dynamically typed language for the JVM, and uses reflection by default to access Java objects. However, you can supply functions with "type hints" that the Clojure compiler can use to optimize the code. With type hints, Clojure runs as fast as Java.
It seems to me that a clever enough compiler could make a good guess about what type a function would receive. If it was a JIT compiler, it could work it out through observation.
Modifiing the structure of your code is a bad thing that you learn at school very soon. Only for some languages. Lisp programmers, for instance, regularly write macros that modify their code.
Also if you do enable variable to be any type and let the structure of your code be modified at runtime in the client browser this a big hole to security for web 2.0 applications Only if you're not sanitizing user input correctly, which you have to do for any remote system anyway. Welcome to web 2.0 security; same as web 1.0 security.
If you find Java's static typing inflexible and restrictive, you're doing it wrong. Have you ever worked with a language that has algebraic data types? I can't see how anyone who's worked with a sufficiently expressive type system could ever see Java as anything other than inflexible and restrictive. What statically-typed languages have you worked with?
Having recently completed a major refactoring of a Ruby project with tens of thousands of lines of code, I can say from experience that refactoring of an app written in a dynamic language can be a colossal pain in the ass. Just finding everywhere that a particular class is being used can take hours or days. Then you're doing it wrong, or at least the original programmers were. Refactoring bad Ruby code is probably harder than refactoring bad Java code, but if your code is decent, I'd contend the opposite is true.
In Ruby, you can construct methods that are more expressive, so the core architecture of your application should be relatively small. Everything else should be business logic and presentation, and separate as much as possible from the underlying architecture. If your application is "tens of thousands of lines of code", then presumably it's an application with dozens of separate chunks of functionality. Why not farm these out into self-contained gems? Then you wouldn't need to refactor the whole lot.
So you better have to explain yourself what's really wrong with the type handling in Java. Type systems can potentially prevent a very wide range of errors at compile time. For instance, how many times have you run into a NullPointerException in Java? Or ran into a race condition when dealing with threads? Or not properly sanitized user data? Data processing loops overrunning? All these things can potentially be caught at compile time by a sufficiently advanced type system, such as in a language like Haskell.
Throughout my career, I've used a mix of dynamically and statically typed languages. In my current job, for instance, I've worked on programs in C#, and programs in Ruby. I get very few errors in Ruby that C#'s type system would have prevented, and those errors that occur are generally quickly apparent. It's pretty unusual to pass the wrong type of object to a function, but it is common (for instance) to have problems with nulls and nils.
Java's type system is geared to address errors that are relatively rare, and easy to catch. In order to achieve this rather unimpressive feat, it sacrifices a whole bunch of functionality that dynamic languages possess. To my mind, it's not worth the trade-off. I'd rather Java restrict nulls, or mutability, or race conditions, or something that results in a lot more errors that passing the wrong type into a function or data structure. Java sacrifices 80% of its functionality in order to catch 1% of programmer errors.
I am not a programmer myself, but i know a bunch, and just about every one I know or have talked languages with systematically abhor Java (the words slow and bloated come up often) I dislike Java, but the JVM isn't slow. On the contrary, it's the fastest VM I can think of, and is pretty close to C++ in terms of performance.
Javascript's object model is simpler, more flexible, and more consistant than Java's object model. Whether it's better depends on your point of view, but it has some advantages.
Static typing is nice when done properly, but Java doesn't do it properly. It manages to be both inflexible and restrictive, and prevents only relatively uncommon errors. I can't think of a single statically-typed language that has a worse type system than Java.
IMO it's actually a silly question, if someone takes a backup of your brain, it's just a backup of your brain. Your original consciousness would remain with your physical brain. You would be dead but a perfect copy of you would live on. Not much use to you. Depends what you think counts as "you". I used to hold the same opinion, but I've since changed my mind. If a copy was made of me, right down to the atomic level, then it's as much "me" as the original.
But even if you don't believe that, you could opt for a gradual upgrade. Gradually replace your neurons with artificial ones - and assuming the artificial ones behaved in the exact manner as the original - you wouldn't have to worry about disconnections of consciousness.
Apart from this there are the technological issues of turning links between neurons to 1s and 0s and back again, the brain/computer interface and the insane amount of storage that would be required...ripping a brain would certainly be a lossy data conversion. Brain/data transfers are the most far-out sci-fi concept there is IMO. You're talking about space habitats in the 26th century, and computer memory is the most far-out sci-fi concept you can think of? No-one has seen a working space habitat, but we've certainly seen storage devices large enough to be capable of housing human consciousness. There's one in your skull right now.
Compared to things like FTL travel, teleportation, time travel, and all the other "superscience" that appears in sci-fi, we at least have an idea of where to begin with reverse-engineering the human brain. Biological science is an established field, and whilst it'll take us a long time to fully document how the human mind works, 500 years seems plenty of time.
And in space, we should build habitats suitable to our evolutionary history. In 500 years, I suspect it will be cheaper to download our minds into orbiting server farms. Why waste energy creating and maintaining an earth-like habitat when you can simulate it inside a computer?
That day would also spell the end of the web. Most sites exist because of ad revenue, you know.
Adblock does not, by default block Google text ads that appear alongside search results. Nor do I have any desire to block them, because they are often useful and relevant.
The problem isn't with ads. The problem is the low signal-to-noise ratio for most online ads.
While I agree with that at some level, I would say there are too many people that have not explored the full range of what Java itself can do and how techniques learned in different languages can be applied using a combination of Java and various libraries.
Some time ago, I had the problem of exporting a tree of database tables into an XML output file. My solution using C# 1.0 was rather unsatisfactory, and in my spare time I attempted to rewrite the core logic in Haskell. Part of this solution was the two-line function below, which transforms a generic grid of data (with each column representing a successive layer of branches) into a list of trees.
I was unable to come up with anything as neat as this in C#, and I can think of no particular feature of Java that would make it any easier in that language. I'd be interested in any solutions in Java that come close to the conciseness of the Haskell code.
And "favoring different kinds of abstractions" is mostly BS. I've written object-oriented code in assembler! It's just a paradigm, and the only thing a language can help you with is syntactic sugar.
I strongly disagree. There are many abstractions commonly used in other languages that are rarely, if ever, used in Java. For instance, Lisp programmers commonly write macros to transform the structure of their code, whilst in Java, it is extremely rare for a library or framework to delve into bytecode manipulation.
Similarly, a common abstraction in Haskell is the monad. To my knowledge, there are no libraries or frameworks that use this abstraction in Java. Again, this may lead one to ask why is such a common and presumably useful abstraction missing from everyone's Java code.
The problem is that Java doesn't handle these abstractions particularly well. In Lisp, code is defined in terms of lists within lists, and this basic syntax makes it very easy to manipulate. Java's syntax is obviously far more complex, and the compiled bytecode bears little resemblance to the original Java, making byte manipulation a very complex operation.
Likewise, Java's primitive type system makes monads a difficult concept to implement at best. A single line of Haskell loses much of it's clarity when reduced to a page of anonymous classes and interfaces, heaped together in a morbid parody of Church's lambda calculus.
I haven't found any complete implementations of monads in Java, so I can only speculate at what the eventual monstrosity would look like. For comparison, we can refer to a simpler construct, the Y-combinator. In Haskell, it can be defined in one line:
In Java, it's... well, it's just a few more lines.
Now, I'm not claiming that it always takes a page of Java and the google-collections library to implement the equivalent functionality of 13 bytes of Haskell. This is obviously an extreme example. However, hopefully it demonstrates my point that there are some forms of abstraction that Java does not take at all kindly to. In this case, lazy evaluation and first class functions.
Like what? Name anything and Java probably already has a library for it. Java is just as flexible as anything these days, and wether your thing in running Ruby on Rails on top of the VM with some Java through in the backend or some functional Groovy work Java has options.
I think you misunderstand me. I'm not criticizing Java's libraries or the JVM. I'm criticizing the Java language.
As for how its limited, just consider the tools used in other languages. Lisp programmers often use macros in their code, because manipulating Lisp code is extremely easy. Java programmers have libraries for generating bytecode on the fly, but they have nowhere near the ease at which S-expressions can be thrown around. As such, libraries or frameworks written in Java that use bytecode generation are relatively rare. In the Lisp world, you'd be hard pressed to find a library that doesn't use macros somewhere.
Similarly, Ruby makes a big deal out of blocks. Java can do similar things with anonymous objects, but again, they're very unwieldy and are not used with the same ubiquity as Ruby uses blocks. Ruby can also add methods to classes on the fly; Java can do this too, via bytecode manipulation, but it's horribly complex compared to Ruby, and thus hardly use.
Another example of a abstraction you don't find in Java is the monad. Used all the time in Haskell, I've never seen a Java implementation. Again, this is because it's so difficult to implement anything that resembles a monad in Java that it's usually not worth the bother.
Note that I'm not complaining about the JVM here. Scala has monads, Groovy has blocks, and Clojure has macros. It's perfectly possible to use these abstractions in the JVM, but usually completely impractical to try using them with the Java language. My criticism, therefore, lies with more with programmers who don't look beyond the language of Java, rather than the VM or standard library that share the same name.
After nearly 20 years of programming experience, I have come to the conclusion that programming languages are totally irrelevant when it comes to "being a master". The real art lies in being able to analyze the problem, and making abstractions to come up with an elegant solution.
The problem with that theory is that different programming languages favour different kinds of abstractions. A programmer only familiar with Java will only be familiar with the abstractions that work well in the Java environment. Compared to some other languages, Java is pretty limited in what abstractions can be practically implemented, so it greatly restricts the amount of solutions available to the programmer.
Page layout is supposed to be its job, and yet it's still very difficult to lay out simple multiple column layouts in CSS with consistent results. Padding and the box model are so byzantine as to confuse even the browser vendors.
I did say that CSS deals with page layout poorly, but it doesn't seem a fundamental failing to me. You could solve it just by adding in better layout controls and deprecating much of the current way CSS handles layout.
I am getting more comfortable with Javascript, though I still think DHTML and CSS are fundamentally fucked, and it really is time, if this web delivery of apps thing is for real, to find some more rational means of actually dealing with dynamic content.
Could you perhaps expand on that? CSS deals with page layout poorly, and it's somewhat badly implemented in IE, but there's nothing I can think of that's fundamentally wrong with it. And I can't think of very much fundamentally wrong with Javascript DOM manipulation, either.
Better? Maybe. Good enough? No.
Of course it's not good enough, but improving the situation in any significant fashion would require getting the banks to move away from using passwords and credit card numbers to verify financial transfers, which are far too easy to spoof.
No its not. Because if you condition users to it, they will always accept it, which allows you a trivial downgrade attack to self-signed HTTPS.
Maybe I misunderstood you. I'm not saying we should condition users to dismiss dialog boxes without thinking. I'm saying that the security benefits of having cheap HTTPS outweigh the benefits of refusing self-signed certificates.
The browser should accept all certificates by default without the user having to click anything, but only mark certificates as "secure" if they've been verified by a third party.
And conditioning users to accept self-signed certs for HTTPS is a mistake.
I disagree. A self-signed certificate is better than no encryption at all. I'd just have browsers accept all certificates, but only display the signature yellow address bar and padlock icon for certificates signed by registered third parties.
Using a database gives you fast lookup, consistency checking, locking against race conditions, enforcement of correct structure, dump and load capability, and a standardized interface.
But databases interoperate poorly with version control systems, have no facility for comments, and work best for data that is pretty rigidly structured. Many server applications for Linux have extremely flexible configurations that don't suit the relational database model.
All this does is breed smarter criminals.
This is probably a good thing. The majority of crimes are committed because the criminal is too stupid to accurately assess risk versus payout. Criminals that make more than the average wage are extremely rare.
He mentions Powershell. Unfortunately, Powershell is extremely slow, even for a shell. It's several orders of magnitude slower than Bash.
Microsoft's natural keyboards are pretty damn good, and half the price of Das Keyboard.
I don't really think the trade-off is in static typing and catching errors.
I'm not so sure. JIT compilation can do a lot to mitigate the performance impact of hash-lookups. The author of Psyco, for instance, holds that an expressive language like Python could theoretically run faster than C, because the compiler has access to more information with which to optimize the code.
My experience with Clojure seems to bear out this claim. Clojure is a dynamically typed language for the JVM, and uses reflection by default to access Java objects. However, you can supply functions with "type hints" that the Clojure compiler can use to optimize the code. With type hints, Clojure runs as fast as Java.
It seems to me that a clever enough compiler could make a good guess about what type a function would receive. If it was a JIT compiler, it could work it out through observation.
Maybe you should program in a dynamically typed language, then :)
for (var i in array) is fragile anyway, and there's nothing that mandates you to override a core class, rather than a wrapper.
In Ruby, you can construct methods that are more expressive, so the core architecture of your application should be relatively small. Everything else should be business logic and presentation, and separate as much as possible from the underlying architecture. If your application is "tens of thousands of lines of code", then presumably it's an application with dozens of separate chunks of functionality. Why not farm these out into self-contained gems? Then you wouldn't need to refactor the whole lot.
Throughout my career, I've used a mix of dynamically and statically typed languages. In my current job, for instance, I've worked on programs in C#, and programs in Ruby. I get very few errors in Ruby that C#'s type system would have prevented, and those errors that occur are generally quickly apparent. It's pretty unusual to pass the wrong type of object to a function, but it is common (for instance) to have problems with nulls and nils.
Java's type system is geared to address errors that are relatively rare, and easy to catch. In order to achieve this rather unimpressive feat, it sacrifices a whole bunch of functionality that dynamic languages possess. To my mind, it's not worth the trade-off. I'd rather Java restrict nulls, or mutability, or race conditions, or something that results in a lot more errors that passing the wrong type into a function or data structure. Java sacrifices 80% of its functionality in order to catch 1% of programmer errors.
You can add, alter and remove methods from an object at runtime, including built-in objects like Array.
Javascript's object model is simpler, more flexible, and more consistant than Java's object model. Whether it's better depends on your point of view, but it has some advantages.
Static typing is nice when done properly, but Java doesn't do it properly. It manages to be both inflexible and restrictive, and prevents only relatively uncommon errors. I can't think of a single statically-typed language that has a worse type system than Java.
But even if you don't believe that, you could opt for a gradual upgrade. Gradually replace your neurons with artificial ones - and assuming the artificial ones behaved in the exact manner as the original - you wouldn't have to worry about disconnections of consciousness. Apart from this there are the technological issues of turning links between neurons to 1s and 0s and back again, the brain/computer interface and the insane amount of storage that would be required...ripping a brain would certainly be a lossy data conversion. Brain/data transfers are the most far-out sci-fi concept there is IMO. You're talking about space habitats in the 26th century, and computer memory is the most far-out sci-fi concept you can think of? No-one has seen a working space habitat, but we've certainly seen storage devices large enough to be capable of housing human consciousness. There's one in your skull right now.
Compared to things like FTL travel, teleportation, time travel, and all the other "superscience" that appears in sci-fi, we at least have an idea of where to begin with reverse-engineering the human brain. Biological science is an established field, and whilst it'll take us a long time to fully document how the human mind works, 500 years seems plenty of time.