Showing posts with label lisp. Show all posts
Showing posts with label lisp. Show all posts

December 10, 2010

Something nice about every language I've used

Inspired by this post (and more great answers on the reddit comment thread), here's one nice thing about each of the languages I can remember using in any meaningful capacity:

Java: I learned to program in this. It led to the creation of the JVM, and while Java isn't my favorite language, the JVM is a pretty sexy piece of technology that enabled a number of other languages (Scala and Clojure most notable) to flourish.

C: The closest thing imperative programming has to "sparse beauty," a la Scheme. Shows you really don't need many bells and whistles to do a job, and do it well.

C++: Back when everyone was using C, it's kind of a technical miracle that Bjarne could create a proper superset on top of C with the features it has. Further, it's still blazing fast; without it we wouldn't have all the video games we love today ^_^.

PHP: Incredibly easy to learn, and no-hassle to set up on a server. One of the matches that lit the web on fire.

Racket (and Scheme applies here too): The language that never lets up. The most delicious learning curve I've ever tasted. Like Wagner's music is jokingly said to be "better than it sounds," Racket is more fun and fulfilling than it deserves to be.

Erlang: Industry-proven functional programming with more concurrency love than 1000 suns. Also the top language for gaining hipster-programmer cred. When you drop this name, suddenly everyone looks at you like "that guy" (you can decide if this is what you want or not).

Haskell: A wolf in sheeps's clothing, the most modern, practical, and supported language with features I think we'll see as necessary in the future. Another candidate for learning curve that keeps on giving.*

SML: A really sick module system for programming in the large. While not my favorite for "programming in the small," an understanding of SML's module system makes you pity that it never really took off.

Ruby: One of the most beautifully designed, fully-realized languages I know. Shows you can make a language that is simple, with practical value for Herp Derp programmers without sacrificing power and flexibility for the craftsmen as well.

Objective-C: The real "C with objects." Message passing with named parameters (and the much more sensible #import rather than #include), this is one time where I'm highly in favor of Mr. Jobs' stubbornness.

Prolog: 10-second youtube video. I mean this in a good way.

Max/MSP: Probably the most fully-realized and pleasing graphical programming environment I know, as well as an example of a damn fine DSL.

Javascript: I don't have to worry about compiler errors! No seriously, prototypical objects for the masses.

Flapjax: Functional reactive programming! An excellent example of functional languages and concepts attacking problems from the language level. Very innovative workaround for the horrors of client-side programming of the time.

Actionscript: Adobe makes it! Like Java, but better (Flash Platform > Swing/most Java GUI's).

*= Small qualification on the learning curve lines: virtually any language takes years of work over dozens of programs to "master." But many times mastering a language means compensating for its weaknesses, not discovering new strengths. That's what Haskell and Racket have given me more than most other languages.

November 13, 2010

The Road to Lisp Survey

I, Paul Meier, do solemnly offer these responses to the Road to Lisp Survey:

When did you first try Lisp (meaning here and throughout the survey "any member of the Lisp family") seriously, and which Lisp family member was it?

I took Lisp seriously after my first exposure to it, in Shriram Krishnamurthi's programming languages course, based on his excellent book, PLAI (download it! it's free!). We mostly used Scheme for the course (the implementation now called Racket), and while I could call the programming from that class my first exposure, I really only explored it during self-study after the course.

In the Preface to his book, Shriram mentioned The Little Schemer as a good introduction to thinking in Scheme. In the Acknowledgments, he said "Please read those magnificent books even if you never read this one" of two books, one of them being Structure and Interpretation of Computer Programs. I picked them both up that Winter, and I was hooked.

What led you to try Lisp?

The answer is really in the next question, but I'll also mention that this was not just my first exposure to Lisp, but functional programming as a whole. While I enjoyed programming to a point, what really interested me in Computer Science was the strong theoretical results we'd achieved: the fact that we could prove undecidability kept me awake for weeks.

So part of my migration to Lisp wasn't just to homoiconic syntax and dynamic type systems: it was also the wonders of functional programming I would find prominently in Scheme.

If you were trying Lisp out of unhappiness with another language, what was that other language and what did you not like about it, or what were you hoping to find different in Lisp?

I took the languages course at the same time I took our excellent graphics course, where we used C++. I found I spent much, much longer debugging the C++ programs, for a much less interesting class of bugs. You'd pull your hair out, looking at memory addresses and pointer values only to find you did your pointer arithmetic wrong (we were investigating a two-dimensional matrix stored as a linear array), or that a state change occurring in an edge case was leaving your program in an inconsistent state. It was frustrating, to say the least.

In Scheme, I was only fixing logical bugs. I spent more time thinking than typing. My programs were shorter and elegant. It's as if, by framing the problem differently, hundreds of edge cases and corner cases simply ceased to exist.

And there's something to that. Removing state means putting a lot more effort up front, but ultimately makes your programs worlds easier to write and maintain after you've invested. Not to mention spending your brain cycles modeling is worlds more fun spending them debugging.

Of course, I didn't know that back then; I moved because I just had the feeling they were doing something right, and I could learn something valuable.

How far have you gotten in your study of Lisp? (I know, that is hard to measure)

This is very hard to say. In many ways, I'm still a novice, since most of my Lisping doesn't take full advantage of macros, Lisp's crown jewel. I'm still much more comfortable in Scheme than CL, Clojure, or Arc; I'd call myself a competent Lisp programmer having written a few small programs and baby scripts, with a toe in advanced and a longing to go expert.

What do you think of Lisp so far?

I think it's still a very advanced, progressive way to approach programming, at least with smaller engineering teams. I'm completely unsurprised it's not used in industry as much; it's a large investment, and languages rely heavily on community. Incidentally, I feel the only real rival to Lisp in caliber would be Haskell, who's unofficial motto is "avoid success at all costs." ^_^

--------------

Also, any of you see atomo? It looks pretty hip, if ambitious...

November 7, 2010

THE LAND OF LISP

It's been a while since I've been able to run through a code book, with life throwing me so many welcome curveballs since the summer. But I'm finally taking the time to work through a book like old times; this go-round is with Conrad Barski's Land of Lisp. I probably wouldn't have gone for it, but the music video he made was just too cute:



The book is peppered with cute cartoons and a whimsy feel that is endearing, not overbearing. I highly recommend it, if only for the comics (though working through the examples is fun, the games you make really highlight Lisp's strengths).

Some may recall that I've dabbled in CL before; sadly that affair was over before it started (curveballs!), but my next project after ScrabbleCheat will likely be in either Haskell or Common Lisp ^_^

And how goes ScrabbleCheat? Quite well, actually! The technologically adventurous can download and play with it now. What I'm working on now is a simple UI in ncurses, which will probably take another week or two. But as soon as that's up, the program should not only be functional (which it mostly is now), but usable!

June 8, 2010

Keep Up that Racket!

PLT Scheme, formerly my favorite Scheme implementation and mentioned before in my writings, has been re-branded as Racket. I'm very excited about this: Racket is a language of unbelievable potential, and hopefully it's re-branding will make people aware of this.

(while it is just a name change and new website, I doubt Clojure would have gotten it's momentum if it were just called "JVM Lisp").

One of the wonderful things about Racket is its mailing list, and a cute discussion there generated a major treasure. Namely, someone brought up that computer programming isn't really that related to computer science, to which someone else mentioned that you could very much be a successful programmer even if you haven't studied the science.

This is sadly true (many people making their livings don't know what they're doing, many examples at The Daily WTF), but then a user named Joe Marshall simply wins:


> It's quite possible to be a productive and successful programmer without having a
> solid understanding of computer science.

That's the problem. Maybe it shouldn't be the case. Variations on this
statement are alarming:

"It's quite possible to be a productive and successful physician without having a solid understanding of medicine."

"It's quite possible to be a productive and successful airplane engineer without having a solid understanding of aerodynamics."

'Rocket Scientist' : 'Newtonian physics'
'Brain Surgeon' : 'neurology'

I attribute this more to the fact that we're living in the cave-writing stages of software: we've had computers for fewer than 70 years, personal computers for maybe 30, and connectivity for less. I'm sure after the invention of the steam engine, all sorts of idiots were designing inefficient, dangerous factories, and we've now got the software equivalent.

I'm lucky in that I got to study the science, and am genuinely interested in it to keep learning. But what a wonderful day when people who develop software who know at least what I do will come standard.

May 9, 2010

PAUL IS BOTHERED

You can talk all you want about 'practicality,' but one way in which I see functional languages will ALWAYS beat imperative is the built-in love of lists. I simply can't express my distaste for always writing:


import java.util.Collection;
import java.util.Iterator;

// crap elided

Iterator<String> iterator = myCollection.iterator();
while (iterator.hasNext()) {
    doSomethingWithString(iterator.next());
}

over, say:


(map do-something-with-string my-collection)

But Paul! says you, Java gives you static typing! The Scheme example above doesn't, so it can get away with that kind of dynamic-language brevity! Well, so does Haskell:


map doSomethingWithString myCollection

and SML:


map(doSomethingWithString)(myCollection)

For fun, lets just see it in a smattering of other languages I've used. Ruby:


my_collection.each { |x| do_something_with_string x }

Erlang:


lists:foreach(fun do_something_with_string/1, MyCollection),

Common Lisp:


(mapcar #'do-something-with-string my-collection)



Naturally, this isn't even the whole picture. The example assumes you're iterating for side effects; if you needed the list with its elements transformed, that would be another 5-7 lines of Java. And the list can only exist because it was constructed to begin with, which if you did it in another class, requires 3-6 more import declarations there.

I know its trendy to hate on Java, and I've mentioned before that PL hating like this is unproductive. Still, we use and work with variable-sized lists all the time, and what functional designers figured out (long, long ago) is that it's quite nice to have them built-in.

Bleh, sorry. Android programming is fun, despite the Java.

I did say "imperative" above, not just Java. Kind of a misnomer, as CL and Ruby, above, provide one-line map and are arguably imperative. In that case, I let my biases shine through and used "imperative" interchangeably with "luddite." But let's never forget our buddy C++:


#include <list>
using namespace std;

list<string>::iterator iter;
for (iter = my_collection->begin(); iter != my_collection->end(); ++iter) {
    do_something_with_string(*iter);
}

PUKE

April 6, 2010

Common Lisp

I've been playing around with Common Lisp recently, using Practical Common Lisp and Let Over Lambda as guides (not gonna lie, having LOL on the spine of your book is wonderful). Last year when I went through my Scheme phase (the original URL of this blog was littleschemer.blogspot.com), I never thought I'd see the day that I'd switch sides.



FWIW, this is my iPhone background image.


I do feel like a traitor though, since even though I'm a theory-head and advocate of FP, I'm loving Common Lisp. There are a few reasons for this:

  • Simpler macros. I'll bet some hardcore Schemers will disagree with me on this, but I feel that defmacro is much, much simpler to learn than syntax-case, and syntax-rules always leaves me wanting more. Maybe I'm deficient, but I took to defmacro immediately, whereas when I want to do anything non-trivial in Scheme, I feel myself always going back to Dybvig's explanations, taking far longer than I'd like.

    While in principle I'm for hygiene as the default, it's not too big an issue in practice. Hoyte gives a great little macro (one of the first in his book) that ensures you fresh variables whenever you want them, without even having to declare them!

  • Language libraries. CL comes with every function you could ever want. It comes back to what Peter Norvig said in Paradigms in Artificial Intelligence Programming (paraphrasing): Scheme is one of the smallest languages to define (< 50 pages), whereas CL is one of the largest (> 1200 pages).

    While some Schemes provide these, since they aren't part of the standard you aren't guaranteed anything across implementations. In fact, my favorite Scheme in terms of libraries (good ole' PLT) even broke across versions when they enforced module declarations at the top of every file.

    Besides, once a Scheme gets these, they stop wanting to be called Scheme.


This isn't to say its all peaches and cream: I still prefer Scheme's single namespace over Common Lisp's, I prefer Scheme's naming conventions (map vs. mapcar, or worse, loop for elem in list collecting). And issues with lambdas, namely sharp-quoting and not being able to place functions in the function position (especially after learning the beauty of Scheme's semantics so well last semester) still throw me for a loop.

But after a year of mounting tension with the residents of Shelbyville, I realize they've got quite a bit right ^_^.