Wednesday, February 29, 2012

Clojure in pure Python is a great idea

Edit: Here's the link

Not good enough for me to do it myself, but I'd be very happy if someone else did it. Why?

You'd give up Java interoperability, but you'd gain interoperability with native code. Python offers excellent C++ interoperability via Boost and other methods, as well as excellent (but limited by the constraints of C) interoperability with Fortran. Further, rpy embeds, more or less, R in Python. It would make Clojure much more suitable for numerical work. For that matter, you could call all of scipy from Clojure. Awesome.


Another reason is that it would reduce the amount of competition between languages. I hate language wars because they're a waste of time. I might prefer one language for a given task, but I use many, so using one doesn't mean you can't use another. Anything that allows you to write in both Python and Clojure is helpful - let the developer make the choice, even on individual sections of code.

Another big advantage is getting us away from Java. The build tools, the classpath, the .com.lengthy.verbose.wtf.on.and.on are inherited from Java, and seriously suck. I guess tail call optimization is possible.

So you could say I'm a fan. Provided that it is possible to implement nearly all of Clojure, to the point that you can be confident that you will be able to write Clojure code for the JVM and expect it to run on the Python VM. It would be necessary to add functions such as Math/pow to get to that point. A lot of work, but definitely valuable. I hope it is viewed as an additional option for Clojure developers, not a threat to the JVM.

{Why am I writing this here? I put all comments on my blog. I don't have the time or interest to get into an internet shouting match.}

Wednesday, February 22, 2012

Preliminary thoughts on Scala vs Clojure

I've been using Scala for a little over a week now. Here are some preliminary thoughts on Scala vs Clojure.

(i) Scala is a better Java. Scala is still Java, in the sense that it is an OOP language requiring you to put a lot of effort into determining what is public and what is private. I've written about alternative approaches to OOP before [here, here, and here]. I don't want to go through the same discussion here (and don't claim to have fully grasped all the issues). I'll just say that I'm not smart enough to keep track of all the things you have to keep track of to do Java-style OOP. I can write pure functions that operate on data structures. I can't keep track of how all the data and methods and private etc. interact with one another. I couldn't do it when I tried Java and I can't do it now.

(ii) I miss macros. That surprised me because I don't write a lot of macros in Clojure. A lot of what I have done in Clojure makes use of Incanter, so it was just simple library calls. I don't even understand macros fully. Yet I miss them when they're not available. I spent a few minutes looking at Scala macros. That was enough.

(iii) Syntax is double-edged sword. I'm a fan of "everything's a list". If anything, I'd prefer to cut down on the amount of syntax that ends up in Clojure programs. Yet "everything's a list" just can't be sold to others. Scala, on the other hand, probably has the best syntax I've seen. I'd imagine that Scala makes a very good first impression. I haven't talked to anyone else about Scala so I don't know.

(iv) Scala performance is better than Clojure's. It's too easy to write slow code in Clojure. The various benchmarks I've seen support this. There are a lot of good things I can say about Incanter, but you wouldn't choose it for performance. I don't mean this in a way to start a flamewar, it's just an observation, and I'd be happy for someone to point out how I'm wrong. By that I don't mean a list of ways to tune my Clojure code. Tuning is a PITA that should be done by the author of the library. If performance is critical, I can't see a reasonable argument for using Clojure rather than Scala.

(v) I do mostly numerical programming. The JVM is a serious drawback for both languages. Beyond that, I don't see much interest from the Clojure community in numerical computing. All I see is Incanter, which doesn't seem to be very active, doesn't offer great performance, and is far from a complete solution relative to R, Matlab, and Scipy. Clojure is focused on other areas, and that's fine, but this is my comparison of Clojure and Scala, and it's what matters to me. On the other hand, Scala is very active in this area. Five years from now Scala will probably be a strong competitor to Matlab, while offering a much better language. It would be interesting to compare Clojure against SBCL for numerical computing.

(vi) Both have adequate IDE support in Eclipse. Counterclockwise is pretty good. The Scala IDE is just unbelievable. You don't need to debug Scala code: you just look at the bottom of the screen to see if there are any errors. You can even understand Scala error messages.

(vii) I probably have a preference for static typing overall, but it depends on what I'm doing and my mood.

(viii) Clojure has some rough edges. The transition to 1.3 coinciding with changes to Clojure/core left me frustrated. I use Counterclockwise with 1.2 and the old Clojure/core. I value my time. I don't think Clojure is where it needs to be in terms of documentation. Also, I really, really wish that those who write Clojure documentation would understand that NOT ALL CLOJURE USERS ARE CURRENTLY EMPLOYED AS ENTERPRISE JAVA DEVELOPERS! I tried Java years ago, hated it, and moved on. I know nothing about Java. It took me quite a while to understand how the hideous "com.Enterprise.Verbose.For.No.Reason" thing works when using libraries. I had to look in a Java book to get the necessary background. I have had a much smoother experience with Scala. Maybe the difference is that I've learned the Java approach by using Clojure.

(ix) Clojure has an impressive set of books available. They all do a decent job of explaining the language. Yet none of them can compete with Programming in Scala by Odersky, Spoon and Venners. You learn a lot more than Scala in that book. I'd highly recommend it to any intermediate programmer, even those who don't plan to use Scala. There are excellent resources available for either language so I don't see this as a reason to choose Scala.

Conclusion: I like the Clojure language better. I'd probably be more productive in Scala because it has a stronger future for numerical computing. I could sell others on Scala, but probably not on Clojure, due to syntax. Neither is going to replace my current combination of R + Fortran for everyday work.

That's a lot more than I planned to write. I'll update as things come to mind or as I learn I was wrong.

Tuesday, February 21, 2012

I understand C pointer syntax, but it doesn't make sense

No, C pointer syntax does not make sense, even if the author of this post understands what it represents. Let me begin by saying that the concepts underlying C pointers are not difficult to understand. You don't even have to know how to program to understand such a simple concept.

The problem is that you have to memorize a bunch of rules that violate good programming language design to use pointers in C. It's such a poor design that anyone with an ounce of programming ability has to say to herself, "That cannot possibly be the correct syntax - you just don't write programs like that!" Then you get used to it, and even though it doesn't make any sense, you're used to it, so you can do it.

What's wrong with float *pf? Well, for one thing, you're all of a sudden using a non-alphanumeric character to name a variable. That's completely inconsistent with the rest of C syntax. It's acceptable for Lisp, but not for C, because * is not acceptable as part of a variable name.

The second thing that's wrong with it is that it implicitly defines another variable, pf. Actually, it also defines **pf and ***pf as well. You can define **pf as (sort of but not really) a matrix, and then that defines *pf for you. One of the first things you learn when programming in C is that you have to define variables before you use them. Except sometimes you don't. They decided to throw type inference into the mix when it comes to pointers. They cleverly hide the type inference part by talking about things like indirection and addresses.

The third thing is that it is just weird to say you can define *pf as a float, and if you drop the first character, you get a variable that's completely different. How about pf for the float and pf.pointer for the pointer?

The fourth thing, which some people think makes sense, is that you use *pf to define a float and then *pf to dereference a pointer. Yeah, that makes sense. They've overloaded the (potentially non-alphanumeric) first character of a variable's name. Bjarne Stroustrup's proposal for overloading whitespace was a joke. C pointer notation is much worse, and unfortunately it was not a joke.

C pointer syntax is Hungarian notation taken to an extreme. There is nothing good about it. If you're able to use C pointer syntax correctly after seeing it for the first time, you're just memorizing language rules without making any attempt to understand the underlying concepts, and you should think seriously about whether programming is for you.

Clearly the author of the blog post I linked above does have programming ability. That's why he struggled for so long. He now understands something that makes no sense.

Friday, February 17, 2012

Scala, clusters, and numerical computing

This post is mostly for my own reference, but I suspect that others might be interested as well. First, a brief explanation. In the C++ (ie, native code) world, it is easy to set up a Linux cluster and run jobs using MPI. Searching for "Java MPI" is unlikely to inspire you to use Java or other JVM languages if you currently use MPI to run jobs on a cluster.

"Cluster" as I'm using it here refers to a group of different physical computers in different locations each working on different parts of the same job. This is usually called a "Beowulf cluster". Simulations can be easy to parallelize because each iteration is independent of all the others, and if you're doing 100,000 simulations on 100 processors, there is never a need for two processors to work on the same job.

It's good to see that Scala has at least two options for running jobs on clusters:

akka - Also available for Java
Spark - Runs on top of Apache Mesos, which itself works with other languages such as Python, Java, and C++

I've not used either yet, but hopefully sometime in the next couple weeks I will have time to compare them. Here are some links to other numerical computing projects that I have or plan to check out.

scalanlp Contains some optimization routines, linear algebra, etc.
scalalab 
JGAP for Scala*
Parallel Colt (Java)
Stochastic Simulation in Java (Java)
jblas (Java)
Rserve (Java)
Call Octave from Java (Java)
Call Scilab from Java (Java)
JPOP* (Java)
JavaNNLS*(Java)
Apache Commons Math (Java) Already part of scalalab, but Clojure or Java users might be interested
Mantissa (Java)
Java Genetic Algorithms Package* (Java)
Michael Flanagan's library* (Java)
Java Matrix Benchmark

* These might be good, but they are smaller projects for which I have little information about the author, so you probably want to investigate before using for anything serious.

Conclusion: the momentum for serious numerical computing on the JVM is with Scala. I'm more comfortable with Clojure than with Scala, but both Clojure and Scala are so much better than the alternatives that I'd be happy to work full time with either. Clojure isn't there yet, let's see how far I can get with Scala. Most of the numerical library links are Java libaries, and will also work with Clojure.

Thursday, February 16, 2012

Some more Scala experimentation

Ended up with some free time to play with Scala again today. Like many programmers, I learn a language by doing the things I do in other languages.

Today's project was to try out jblas. I gained a greater appreciation of the language from just a few lines of code. The (simple) challenge: create matrix A and matrix B filled with random numbers, then multiply them. As a baseline, in R this can be done using three straightforward lines of code:

A <- matrix(rnorm(12),4,3)
B <- matrix(rnorm(12),3,4)
C <- A %*% B


Here is the Scala code:

object tryblas {
  import org.jblas.DoubleMatrix
 
  def main(args: Array[String]) {
    val A = DoubleMatrix.randn(3,4)
    val B = DoubleMatrix.randn(4,3)
    val C = A.mmul(B)
  }
}

Type inference means I don't have to specify that A is "new DoubleMatrix" - the language figured that out for me! It's more lines than the R program, but not by much. There's a little overhead in a Scala program, and you have to import the jblas library. The Scala IDE even allows you to see the inferred type of A, B, or C by placing the cursor over the name. Impressive! The Java approach for some reason seems reasonable when I use Scala.

Wednesday, February 15, 2012

Calling R from Scala

My main programming language is still R. Incanter, while a nice attempt, is definitely not anywhere close to allowing Clojure to be a replacement for R. The JVM is not suitable for the numerical programming I do, and I find myself spending too much time trying to figure out how to change the code to speed it up.

Thus, as I've started learning Scala, I want to make sure I've got the backup of easy interoperability with R. That's basically what I did when I started learning Clojure. Here is my attempt to do the same thing in Scala. I'm still a beginner, so I won't claim to be able to write good Scala code yet.

My preference when using JVM languages is Eclipse. For Scala, there is an excellent IDE available. I followed the usual instructions to install it. (There is plenty of information on the internet, but it's basically pasting the link they provide into Eclipse, clicking some buttons, and restarting).

I switched to the Scala perspective, started a new Scala project, and added a new file under src. I then started typing. I was really impressed with the Scala IDE. It's still early in this adventure, but based on what I'd read, I was expecting it to be a piece of garbage. It was incredible for the small things I did with it. I especially like how it points out errors while you type. It's just a pleasure to use.

To access R, I downloaded the two jar files that are made available for Rserve. I use Linux, so I opened R in a terminal window, did "library(Rserve)", then "Rserve()".

Back in Eclipse, I right-clicked on the project name, went to "Build Path", then "Add External Archives...". I chose Rengine.jar and then RserveEngine.jar. Those names appeared under "Referenced Libraries" below the project name.

After a few small mistakes, this is the program I came up with. (It's released under the GPL version 2 or greater if you're wondering.)

object rs {
  import org.rosuda.REngine
  import org.rosuda.REngine.Rserve.RConnection
 
  def main(args: Array[String]) {
    val c = new RConnection
    val d = c.eval("rnorm(10)")
    val e = d.asDoubles
 
    for (i <- 0 until 10) {
        println(e(i))
    }
  }
}

Edit: Scala has a better way to print an array than the C-style for loop that I used. You can replace the for loop with  

println(e.deep.mkString("\n"))

I chose "Run" from the menu, followed by "Run" again. After a brief wait (presumably for compilation), I got the following output:

1.1357939434863817
0.45168475066687624
0.8312101791389808
-0.8825102796935446
0.9597726735219193
0.5916220359121344
-0.8979526251577276
0.2217958737969706
-0.013414880990143055
0.021108802828942192

That's it! Super easy. I called R from Scala, had R generate 10 random numbers, shipped those random numbers back to Scala, and printed them out. I can now do anything with "e" that I would do if I had created the random numbers in Scala.

The only drawback is all the syntax. I'm resigned to the fact that most programmers think syntax is good.

Friday, January 20, 2012

stackoverflow needs tweaking

stackoverflow is a wonderful site. It's the first place I go when I have a question related to programming.

Unfortunately, I think it needs a few tweaks. My sample may be small, but lately (the last few months) I've been seeing too many cases where there was a cry of "Duplicate! Duplicate! Duplicate!" or even closing the question. That wouldn't be a bad thing if Question A was, 'What does "Error: Variable not defined" mean?" and Question B was, 'I got this error "Error: Variable not defined". What does it mean?"

The problem is that in many cases those voting to close are trolling rather than looking out for the site. In some cases it is probably just trolling by the immature, with too much time on their hands and too little common sense, but in others it is regular users having fun with power.

Here is one good example. The OP lists a couple of things he's been doing to debug his programs and asks for other suggestions. If that's not a perfect question for stackoverflow, nothing is.

Yet it was closed on the grounds that "We expect answers to generally involve facts, references, or specific expertise; this question will likely solicit opinion, debate, arguments, polling, or extended discussion." Good chance that the trolls voting to close have never written a line of R code.

Here is another example. It was reopened, but as user Dan Burton wrote in his comment, "I checked the profiles of the 5 people that closed this, I'm rather appaled that none of them have made a single contribution to the scala tag."

By the standard that seems to be in place right now, even the question I started with, where the user gives an error message, should be closed. There are multiple reasons you might get a certain error message. That leads to opinions rather than facts, because you'd have to make a judgement about the most likely reasons for a certain error to occur in a given language. It might also be interpreted as a question not about a programming language, but rather what is wrong with the programmer's training that would make him arrive at that error message. (If you think I'm stretching things, dig around on stackoverflow and look at the closed questions.)

My goal, though, is not to talk about these specific cases. Maybe they are terrible examples - whatever. My point is that the same thing happens again and again, and it is creating a hostile environment, particularly for new programmers. It used to be that I could recommend stackoverflow for someone learning a language, but I've stopped. It is very discouraging to ask what you think is a reasonable question and then be subjected to a public flogging. (Even when the question is not closed, the answers are more harsh than a couple of years ago.)

Traditional trolling is bad enough, but at least you can delete or ignore those comments and get on with your business. This new-fangled trolling puts your own posts on the line, and the "closed" message is an official "you don't belong here" message, sent by stackoverflow.com, that the whole world can see. That's kind of hard to ignore, particularly if you used your real name.

Maybe one solution would be banning the close trolls for a week if they vote to close two questions in a 30-day period that are then reopened. Cries of duplication are not as easy to monitor, but they're more in line with traditional trolling, so I don't know that it is as much of a concern. Whatever the solution is, something has to be done to make the site friendly again.

Edit: Just came across this gem. Somebody named Michael Petrotta explained the reason for his vote to close: "@Jay: I was one of the people who voted to close. I thought you might be interested in my reasons. I don't program in C++, and I don't feel much, one way or the other, for the language or its adherents. I read your "question", and saw an attack on a project, with a lot of nasty name-calling. I read the answers so far, and saw a bunch of defensive, content-light replies. I didn't see any value in the question or its answers to date, and I voted to close."

So you've got someone who admits he knows nothing about C++, doesn't care about C++, and he's voting to close the discussion? And he's allowed to continue trolling?

Saturday, January 14, 2012

Use Counterclockwise or Clooj if you want to start with Clojure

It appears that I didn't do a good job of writing my previous post about Emacs and Clojure. I was trying to give a flavor of what someone new to Clojure would think when encountering "Emacs + Clojure is the best development environment". Seriously, getting it set up sucks. Really bad. I speak from experience, having tried to get someone set up using Clojure and Emacs recently.

What you should do is use Counterclockwise. It's wonderful. It's easy to set up. It has lots of features. It's a joy to program in Clojure when using Counterclockwise. That's what my friend is now using.

The other alternative is Clooj. That is truly the easiest way to get going. Just download and run. The disadvantage is that Swing apps don't look that great on Linux. I've gone through all the guides but the fonts still aren't what I want. To my knowledge it doesn't work with dual monitors. But if you want to get started quickly, you cannot possibly do better than Clooj.

Note: I'm not saying you shouldn't use anything else, just that these are awesome for beginners, and others may or may not be.

Friday, January 13, 2012

Is this a good introduction to Clojure?


So I wanted to help someone get started with Clojure today. For those who haven't done much with Java before, the incredible overhead associated with doing the most trivial tasks leads to a bad impression.

To make matters worse, I was trying to set up Emacs for use with Clojure. I'm not an Emacs noob. I used ESS as my main development environment several years ago, but was not impressed, and moved on.

[Edit: Used bold font to emphasize that I'm writing from the perspective of someone who decided he'd try Clojure using Emacs. My personal recommendation is to use Counterclockwise or Clooj.]

This is what someone new to Clojure would experience.

Go to the main Clojure page instructions.

"Install clojure-mode."

Don't know what that means, but I'll click the link.

"If you use package.el, you can install with M-x package-install clojure-mode. Otherwise you can do a manual install by downloading clojure-mode.el and placing it in the ~/.emacs.d/ directory, creating it if it doesn't exist. Then add this to the file ~/.emacs.d/init.el:"

Well, not being a total Emacs noob, I tried M-x package-install clojure mode.  I got [No Match] in return.

What is clojure-mode.el? Where do I download it? Google found it for me. I downloaded it to the ~/.emacs.d directory. I added the lines to init.el (though I had to create that file, something the instructions didn't mention).

The vast majority of new Clojure users would have given up by now. Users should not have to figure things out for themselves - that is the purpose of documentation.

So let's move on. There's a discussion of how to set up package.el. Okay, that doesn't apply to me.

Then there's a discussion of clojure-test-mode. It says "This source repository also includes clojure-test-mode.el, which provides support for running Clojure tests (using the clojure.test framework) via SLIME and seeing feedback in the test buffer about which tests failed or errored. The installation instructions above should work for clojure-test-mode as well."

So do I need it? Is it something that most users install? I'm going to skip it. I can do tests when I get to that point.

Then there's something about paredit, which I hate, but it's recommended for all users.

Following that, there's a section titled "Basic REPL", which says, "
Use M-x run-lisp to open a simple REPL subprocess using Leiningen. Once that has opened, you can use C-c C-r to evaluate the region or C-c C-l to load the whole file.
If you don't use Leiningen, you can set inferior-lisp-program to a different REPL command"

The only way you'd have any idea what that means is if you knew beforehand. That may have set a record for the least informative paragraph ever written. I get tired when I read something like that. What is meant by "different REPL command"? Heck with it, I'm returning to the main page. {Note: this is explained on the main page, but the reader isn't told that.}


I created a new clojure file in Emacs (ending with .clj). There's no automatic indentation! How on earth do you write Lisp code without automatic indentation?

Eventually I got it sort of working, though I never got Clojure 1.3.0 to work. This is not a pretty introduction to Clojure. {I'm not saying it's my introduction to Clojure. It is the introduction to Clojure for anyone who reads Emacs + Clojure is the best alternative.} There's a lot of room for improvement.

I recommend immediately eliminating all references to Emacs when talking about Clojure, with an exception for "Don't waste your time with Emacs if you want to learn Clojure."

Friday, January 06, 2012

The book the world needs

The world needs "Introduction to Functional Programming Using Clojure".

This is needed for at least two reasons. First, the existing books on Clojure require an understanding of basic functional programming. All of the currently available books do a good job of explaining the language. For the average Java or Python programmer, though, it would be tough to learn Clojure if the only resource were one of those books (or all of them, for that matter).

Second, "introductions" to functional programming are usually too academic. SICP, for as much as I love that book, is a book about computer science, not software development. Scheme will never, ever be a programming language embraced by industry. That doesn't mean there's anything wrong with Scheme, but it does mean that if you use Scheme, the perception will be that functional programming is not something you'd do with a "real" language, so I guess that is something wrong with Scheme.

I've been reading about Standard ML recently, and while I have learned a lot, I can't imagine anyone taking ML (SML or OCaml) seriously. I mean, in the sense that the perception would be any better than the perception of Scheme. Moreover, I've tried to read about Haskell, but it's hard to go more than about five minutes without falling asleep. There's just too much religion about pure functional programming. I can see why it appeals to mathematicians, and I can see the point of Steve Yegge's post on Haskell.

Even worse, there's discussion of type systems, which is an advanced topic. It's my belief that dynamic typing is better for beginners. Don't get me wrong: on technical grounds, the ML and Haskell crowds might be right. I'm not sufficiently informed to take sides in the debate. It's just a matter of perception, and ML and Haskell are non-starters IMO.

Clojure's not-so-secret weapon is the JVM. It can run any Java libraries, and thus it has instant credibility. Unlike Scala, it has dynamic typing. It has the coolness factor, too, because of all the concurrency-related stuff that makes it appear to be cutting edge. The language has an outstanding community with members that have - get this - people skills. The creator gives interesting talks. He is happy to incorporate academic ideas, yet comes at everything from a practical perspective, based on years of real world software development.

Perception matters. Clojure may be what those of us who believe in functional programming have been waiting for, in terms of acceptance. The fans of Scheme, Common Lisp, Haskell, ML, and all other functional languages should be happy about this. Clojure is the first functional programming language that doesn't have to worry about the perception problem. Once a functional programming language, as opposed to functional features in non-functional languages, gains acceptance, developers will ask "Which functional language should I use?" Then the door is open for all the other languages.

So back to the book. I promise I'll preorder it when it becomes available. You can even use my title.

Friday, November 25, 2011

Getting a USB Printer Working on Linux Mint 12

Plugged in my USB LaserJet, and it didn't work. I tried hp-setup and localhost:631, but it kept saying nothing was detected.

After some searching, I found out this was a big problem in Ubuntu 11.10.

My solution:
1. Installed the latest available Linux kernel.
2. Added the Ubuntu Precise repo in Synaptic, reloaded the package information, and installed the latest available cups package (also libgnutls and a few other cups-related packages).
3. Disabled the Precise repo. Failure to do so would lead to many tears after I completely messed up my OS.
4. Rebooted and tried hp-setup. Still didn't detect anything.
5. Went to localhost:631 and tried to detect a new printer. Nothing. Experienced an emotion similar to frustration but when you know you are eventually going to get it to work.
6. Entered "nano /var/log/syslog" at the command line after unplugging and replugging the printer. Scrolled to the bottom of the file. It gave me the printer's URI, showed the printer's name, and said it was "re-enabled".
7. Scratched my head.
8. Went back to localhost:631, clicked the "Administration" tab, clicked the "Manage Printers" tab, saw my printer listed. Felt strange emotions, one of which was joy that I had my printer detected, another of which was confusion, as in "is this interface designed optimally?"
9. Printed a test page. It worked.
10. Wrote a blog post in case someone else encounters the same problem.

Monday, November 14, 2011

Wireless on Ubuntu 11.10 and Mint 12

Ubuntu 11.10 has managed to make the wireless internet on my laptop not work. They're great at introducing bugs that never get fixed: this is the only distro with that problem, and I try a lot of distros. The bug carried through to Mint 12 RC, which is of course built on top of Ubuntu 11.10.

I had to install wicd and completely remove network-manager. If you don't remove network-manager, you will get a "Connection Failed: Bad Password" error from wicd if you're using WPA2.

Wednesday, November 02, 2011

Chainloading GRUB 2 from GRUB

I installed PCLinuxOS on my laptop (more on that some other time - I was impressed). Among the other OSes on there is Debian Squeeze. The problem is that Debian Squeeze uses Grub 2, while PCLinuxOS uses Grub.

After some fruitless searches and guesses as to what to do (Grub knowledge doesn't help much with Grub 2) I decided to check the Arch Wiki. As usual, the answer was there. Add the following entry to /boot/grub/menu.lst in PCLinuxOS:

title Debian
root (hd0,4)
kernel /boot/grub/core.img

where root (hd0,4) tells Grub that Debian is installed on /dev/sda5.

Monday, October 31, 2011

Some additional perspectives on OOP

I did some research this weekend about OOP. I more or less took it for granted that OOP is what it is and didn't think much about it until just recently. Nothing new, but some links that I found interesting. I plan to add more when (if) I find them.

Paul Graham (the world's only celebrity Lisper)
Why Arc Isn't Especially Object-Oriented
The Hundred-Year Language

Joe Armstrong (creator of Erlang)
Ralph Johnson, Joe Armstrong on the State of OOP
Why OO Sucks

Jeff Atwood
Your Code: OOP or POO?

Karsten Wagner
OOP is Dead

Alan Kay (who coined the term)
Dr. Alan Kay  on the Meaning of “Object-Oriented Programming”
prototypes vs classes was: Re: Sun's HotSpot

Generic programming vs object oriented programming
Type erasure
Object Orientation is a Hoax

Richard Gabriel and Guy Steele
Objects have failed
Objects have not failed

Other
Problems With Existing Oop Evidence
OOP Criticism
SICP (the course, not the book)
OOP in Scheme
OOP vs type classes
Haskell vs OOP
A fresh look at OOP with concurrent objects
Teaching FP to Freshmen (The comments are informative, as it's clear the OOP supporters are not willing to defend Java/C++-style OOP. Yet for all practical purposes Java/C++-style OOP is OOP.)
Bjarne Stroustrup keynote at GoingNative 2012 I can't find the quote right now, but Stroustrup makes it clear that C++ is much more than an OOP language. He says something along the lines of, "inheritance can sometimes be useful".
Stop Writing Classes
HN Discussion of Stop Writing Classes

Of course, there are alternatives to what is usually called OOP. As I've learned, it's tough to even get a definition of OOP.
Rifle-Oriented Programming with Clojure

I'm not anti-OOP. I just think there are better ways to do what is done in C++ or Java.

Friday, October 28, 2011

Restarting sound on Debian Squeeze

Finally found something that works. Many thanks to the author of this post.

sudo /etc/init.d/alsa-utils stop
sudo alsa force-reload
sudo /etc/init.d/alsa-utils start

Clojure and OOP, part II

I gave some thoughts about Clojure and OOP last week. Now that I've got a little spare time, I want to finish those thoughts.

First, I want to link to this post by Stuart Halloway. It was one of the first posts I read on Clojure (and potentially the first time I had heard of Clojure). Without it I may not have even bothered with Clojure. I'm not a big fan of OOP, and don't use it that much, but I didn't think I could completely give it up.

Encapsulation

I didn't address the issue of encapsulation at all in my previous post. That's because, to me, encapsulation has never been a big issue.* In C++, you declare the inner workings of your classes to be public, private, friends and probably some others that I don't know. It's similar to running a web service. You can't open everything to anyone who wants it.

To be honest, I've never been in a situation where it would have been worth the work to set up an elaborate system in which I define who gets access to what. If there is a piece of data that should be accessible to the outside world, why can't I just use getters and setters? If there's no "get" defined, then I shouldn't be accessing the data.

Maybe to better summarize my experience, I'm not disagreeing with the concept of restricting access to data. What I don't see is how declaring public, private, friends, and whatever, and all the complexity it adds, plus all the work it creates (you have to do it for every class) is better than getter and setter functions combined with common sense and a few simple rules. The C++ approach seems no more reasonable than Haskell's purity requirement. Trying to debug a complicated OOP program is no fun. Maybe I work on smaller projects and don't have ten million lines of code and a hundred programmers of varying quality working with me, so my observations don't carry over to those situations.

For what it's worth, here is Rich Hickey's answer to an interview question by Fogus: "Following that idea—some people are surprised by the fact that Clojure does not engage in data-hiding encapsulation on its types. Why did you decide to forgo data-hiding?"

(Warning: partial quote) "...And if you have a notion of “private”, you need corresponding notions of privilege and trust. And that adds a whole ton of complexity and little value, creates rigidity in a system, and often forces things to live in places they shouldn’t.... If people don’t have the sensibilities to desire to program to abstractions and to be wary of marrying implementation details, then they are never going to be good programmers."

I see nothing controversial about that perspective.

Clojure and Learning OOP

I included the word "learning" in the title of my earlier post. I would argue that Clojure is a much easier way to learn about the underlying concepts of objects (but using maps), polymorphism, and inheritance. These are concepts that every programmer should understand and use.

I would go further, though. Even if you want to use OOP in Java or C++, you're better off to start with Clojure. The advantage of Clojure over Java/C++ is that you can learn one thing at a time. It's very easy for anyone to understand what's going on when you introduce a single concept. With Clojure, the concepts are well-motivated.

In Java or C++ you get hit with everything at one time. There's a lot of coupling. The degree of difficulty rises very quickly with lines of code when someone is trying to learn something. Introducing the grouping of related data, methods, and the system of privileges all at once is not only too difficult, there's no motivation. I've been programming for decades, and I don't see a need for C++-style encapsulation. How is a new programmer supposed to understand?

Only then do you get into polymorphism and inheritance, concepts they have a reason to learn. Give me an hour with a new programmer and I'll have him doing polymorphism and inheritance, and he'll have at least a small understanding of what they are and why he'd want to use them. Then put him in a class on Java or C++ and he'll have no problems. That's why you're better off to start with Clojure even if the goal is to train them in a more "practical" language.

Parenthesis Whining

As an aside, for those who think the use of parenthesis makes Lisp unsuitable for teaching programming, let me present you with Hello World! in Java:

class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

In Clojure, Hello World! is

(println "Hello World!")

One set of parenthesis vs two in the Java program. Plus the Java version has two sets of {}, class, public, static, void, System.out, and String[]. If that doesn't make a programming newbie vomit, nothing will.

As with my other post, I'll conclude by admitting I'm not an OOP expert. I appreciate any comments you might have.


* If it were, I would have to stop programming in R, because I'm not aware that R offers real encapsulation.

Friday, October 21, 2011

Clojure, a great way to learn OOP

Edit: There are two parts to this post. You can read the second part here.



Clojure is not sold as an OOP language, but it is a great way to learn OOP concepts. I had the (mis)fortune of learning OOP by using C++. I actually tried to learn OOP with Java and Python, but the problem was that the examples were so completely pointless that I was able to learn how to do OOP in those languages, but I never learned what OOP actually is. I had to learn that while using C++ to do things that made sense.

I will admit that I'm not a big fan of OOP. I always read that it reduces complexity, that it makes it easier to model your problem, but in most cases I didn't see that the benefits outweighed the overhead.

I've learned something while using Clojure. Nobody really cares about OOP. We care about what OOP does for us, and you can get the benefits of OOP without the BS of C++/Java-style OOP. Objects and polymorphism are convenient. Clojure has made me realize that there are alternative (and IMO far better) ways to get the benefits of OOP.

Here's a quote from Practical Clojure by Luke VanderHart and Stuart Sierra (which I highly recommend if you have no knowledge of Clojure): "The most important example is that maps can do 90 percent of what objects do in an object-oriented program. What real difference is there between named properties of an object and a key/value pair in a map? As languages like Javascript (where objects are implemented as maps) demonstrate, very little." It was nice to see in print something that I've been realizing for myself.

Maps and multimethods are not only very easy to understand, it's tough to learn them without also knowing why you'd want to use them. There's so much formal BS with C++/Java OOP that someone new to the language can't really capture everything. With Clojure you do a lot less and get the same benefits. It's also a natural part of programming in Clojure, even if your program is only 40 lines long, which means it's perfect for introductory programming classes. OOP is sold in the C++/Java world as a way to handle large-scale programs. There's no reason for that to be the case.

It seems strange to say it, but using Clojure has pushed me in the direction of OOP.

{I am not claiming to be an expert in OOP. Take my comments as coming from someone who is a little bit more than a beginner when it comes to OOP. I'd love to hear your thoughts if you disagree. I might learn something.}

Monday, October 17, 2011

Installing a Network Printer on Scientific Linux 6.1

Took me a while to figure this out. Can't use the http://localhost:631 configuration window. Have to go to > System > Administration > Printing. Click on New. Click on Find Network Printer. Enter the IP address in the text box next to "Host...". Click on Find. The rest should be straightforward.

I had to find the IP address by printing the network configuration page from my HP wireless printer.

Friday, October 07, 2011

Adding existing Clojure files to a project in Counterclockwise

I haven't done this in a while, and it took me a while to find out how to do it again. {Insert rant about how things get done in the Java world.}

Under the project name, right-click on "src". Click on Import.... Under "General" click on "File System". Click next.

Click on the Browse... button and select the directory (has to be different from the current project directory).  Check the boxes beside the names of the files you want to add.

Not exactly the most intuitive procedure, but par for the course in the Java world.


Tuesday, September 27, 2011

Why do I still use newLISP?

One of the big* unanswered questions in the world today is why I use newLISP if I am using Clojure. I use R because that's what I've been using for years, I use Fortran because I need speed, and I use Clojure because I want Lisp. So what does newLISP bring to the table when I'm already using Clojure?

Here are a few thoughts:

1. Java is heavy. For example, I work with sockets, and Clojure/Java is overkill for that.

2. You sometimes need an understanding of the Java classpath and all that jazz, and I don't possess that understanding. I can make it work (so far) but I'm not a Java developer and it gets to be a nuisance. The Java build system is a perfectly acceptable reason to avoid Clojure altogether.

3. Another is here:
http://stackoverflow.com/questions/840190/changing-the-current-working-directory-in-java
http://stackoverflow.com/questions/3921744/how-do-i-change-directory-in-command-line-with-clojure


I'm sure you can do what you need to do in Clojure, but I don't want the headache. With newLISP, it's straightforward, and I don't have to learn a new approach for no particular reason.

4. It's easy to call C libraries from newLISP (some of the time anyway). It hasn't been a pleasant experience when I've tried to call C from Java in the past. I'm well aware of SWIG, but SWIG is hardly a fun experience, it's just less painful than the alternatives.


I could add more examples, but the reasoning would be the same. It's partially a matter of scripting language vs full-blown programming language, and partially a matter of JVM vs native platform. I'm probably not going to use newLISP for a big simulation, but there are times that it is the best choice.

I'm not claiming Clojure or any other Lisp can't do these things. Further, I could use Python, Ruby, or Perl for all of my scripting needs. I just find newLISP to be the best solution for me.

* Definitions of big may vary.