Trying to learn: Object Reorientation, and generic functions in LISP! - lisp

im reading Practical common Lisp as a result of another question.
I just read chapter 16 and 17 where you can find how LISP manages objects. But after a couple of years of thinking how Java manages objects, i cant really seem to understand how you would implement bigger architectures in LISP using the CLOS.
So i ask you guys for some 20-50 pages reading about CLOS applied to bigger architectures than simple examples. Maybe a couple of blogpost or even experiences!
TY

If you would like to get hold of the book, "Object-Oriented Programming in COMMON LISP" by Sonja E. Keene, Chapter 11 (Developing an Advanced CLOS Program: Streams) contains a non-trivial example with multiple inheritance spanning about 40 pages.
Eight classes are discussed in detail (stream, input-stream, output-stream, bidirectional-stream, character-stream, byte-stream, disk-stream and tape-stream). Concrete classes that a user would be expected to create instances of are then derived using multiple inheritance.
It's more substantial than the bank account example in Practical Common Lisp. You might also find the rest of Keene's book useful in gaining a deeper understanding of CLOS: the whole book is about CLOS.

If you really want to understand CLOS, you can go back and read The Art of the Meta Object Protocol, which provides the basis and the underlying code for Closette, a subset version of CLOS.

Perhaps take a look at the example applications that are walked through in the later chapters. You will see that classes and objects are just another tool in your box. Resist the urge to program Java with Lisp syntax.
Another place to look at is Successful Lisp, chapters 7 and 14 for the basics, and chapters 31 and a part of 3.10 are about packages and handling large projects.
Some Lisp guru (it might have been Paul Graham, but I am not sure) once said that he has not needed CLOS at all yet.
edit: I think that your confusion may come from the fact that in Lisp, you do not use the class system for organizing namespaces. This is done separately; the two do not really have anything to do with each other.

We at Weblocks also use the CLOS heavily, so you might want to browse the source a bit.

Bigger CLOS applications are
1) CAPI from Lispworks
2) cl-http webserver
3) a very large CLOS package is CLIM
4) if you like OpenGenera (that's a Lisp OS using Common Lisp and some predecessor ZetaLisp
5) a smaller package is http://www.cliki.net/mel-base
Regards
Friedrich

Related

Dynamic typing and programming distributed systems

Coming from Scala (and Akka), I recently began looking at other languages that were designed with distributed computing in mind, namely Erlang (and a tiny bit of Oz and Bloom). Both Erlang and Oz are dynamically typed, and if I remember correctly (will try to find link) people have tried to add types to Erlang and managed to type a good portion of it, but could not successfully coerce the system to make it fit the last bit?
Oz, while a research language, is certainly interesting to me, but that is dynamically typed as well.
Bloom's current implementation is in Ruby, and is consequently dynamically typed.
To my knowledge, Scala (and I suppose Haskell, though I believe that was built initially more as an exploration into pure lazy functional languages as opposed to distributed systems) is the only language that is statically typed and offer language-level abstractions (for lack of a better term) in distributed computing.
I am just wondering if there are inherent advantages of dynamic typing over static typing, specifically in the context of providing language level abstractions for programming distributed systems.
Not really. For example, the same group that invented Oz later did some work on Alice ML, a project whose mission statement was to rethink Oz as a typed, functional language. And although it remained a research project, I'd argue that it was enough proof of concept to demonstrate that the same basic functionality can be supported in such a setting.
(Full disclosure: I was a PhD student in that group at the time, and the type system of Alice ML was my thesis.)
Edit: The problem with adding types to Erlang isn't distribution, it simply is an instance of the general problem that adding types to a language after the fact never works out well. On the other hand, there still is Dialyzer for Erlang.
Edit 2: I should mention that there were other interesting research projects for typed distributed languages, e.g. Acute, which had a scope similar to Alice ML, or ML5, which used modal types to enable stronger checking of mobility characteristics. But they have only survived in the form of papers.
There are no inherent advantages of dynamic typing over static typing for distributed systems. Both have their own advantages and disadvantages in general.
Erlang (Akka is inspired from Erlang Actor Model) is dynamically typed. Dynamic typing in Erlang was historically chosen for simple reasons; those who implemented Erlang at first mostly came from dynamically typed languages particularly Prolog, and as such, having Erlang dynamic was the most natural option to them. Erlang was built with failure in mind.
Static typing helps in catching many errors during compilation time itself rather than at runtime as in case of dynamic typing. Static Typing was tried in Erlang and it was a failure. But Dynamic typing helps in faster prototyping. Check this link for reference which talks a lot about the difference.
Subjectively, I would rather think about the solution/ algorithm of a problem rather than thinking about the type of each of the variable that I use in the algorithm. It also helps in quick development.
These are few links which might help
BenefitsOfDynamicTyping
static-typing-vs-dynamic-typing
BizarroStaticTypingDebate
Cloud Haskell is maturing quickly, statically-typed, and awesome. The only thing it doesn't feature is Erlang-style hot code swapping - that's the real "killer feature" of dynamically-typed distributed systems (the "last bit" that made Erlang difficult to statically type).

Teaching Programming Best Practices to Perl Developers

I have been delivering training on Programming Practices and on Writing Quality Code to participants who have been working on Java since sometime. Object Oriented Analysis and Design is the base and I cover S.O.L.I.D. Principles and excerpts from books like Clean Code, Code Complete 2 and so on.
I am scheduled to deliver training to Perl Programmers(with less than 1 yr. exp. in Perl) in two days and they do not use the Moose(an extension of the Perl 5 object system which brings modern object-oriented language features).
I am now confused as to how to structure my training as they don't follow OOPs.
Any suggestions?
Regards,
Shardul.
Even without Moose, object-oriented programming in Perl is quite possible, and very common. Many CPAN modules offer their functionality through an object-oriented API, even if many of these also offer a non–object-oriented API. (A good example of this duality is IO::Compress::Zip.) Obviously the norms of object-oriented design in Perl are somewhat different from those in some languages — encapsulation is not enforced by the language, for example — but the overall principles and practices are the same.
And even without any sort of object-oriented programming, Moosish or otherwise, there's plenty to talk about in terms of laying out packages, organizing code into functions/subroutines/modules, structuring data, taking advantage of use warnings (or -w) and use strict and -T and CPAN modules, and so on.
I'd also recommend Mark Jason Dominus's book Higher-Order Perl, which he has made available for free download. I don't know to what extent you can race through the whole book in a day and put together something useful in time for your presentation — functional programming is a bit of a paradigm-shift for someone who's not used to it (be it you, or the programmers you're presenting to!) — but you may find some useful things in there that you can use.
A lot of the answers here are answers about teaching OOP to Perl programmers who don't use it, but your question sounds like you're stymied on how to teach a course on code quality, in light of the fact that your Perl programmers do not use OOP, not specifically that you want to teach OOP to non-OO programmers and force them into that paradigm.
That leaves us with two other paradigms of programming which Perl supports well enough:
Good ol' fashioned Structured Programming also Modular Programming
Functional programming support in Perl (also Higher-Order Perl)
I use both of these--combined with a healthy dose of objects, as well. So, I use objects for the same reason that I use good structure and modules and functional pipelines. Using the tool that brings order and sanity to the programming process. For example, object-oriented programming is the main form of polymorphism--but OOP is not polymorphism itself. Thus if you are writing idioms that assist in polymorphism, they assist in polymorphism, they don't have to be stuck in some ad-hoc library "class" and called like UtilClass->meta_operator( $object ) which has little polymorphism itself.
Moose is a great object language, but you don't call Moose->has( attribute => is => 'rw', isa => 'object' ). You call the operator has. The power of Moose lies in a library of objects that encapsulate the meta-operations on classes--but also in simple expressive operators that the rather open syntax of Perl allows. I would call that the appreciation of solving the problems that OOP solves with objects.
Also, I guess I have a problem with your problem, because "not OOP" is a big field. It can range from everything-in-the-mainline coding to not-strictly-OOP (where the process of programming is not simply OOP analysis). So I think you have to know your audience and know what it is they use to keep that code structured and sane. I can't imagine a modern Perl audience that isn't at least object-users.
From there, Perl Best Practices (often abbreviated PBP) can help you. But so would learning that
simply because OOP is one of the best supports for polymorphism it isn't polymorphism in itself
simply because OOP is one of the best supports for encapsulation it isn't encapsulation in itself.
That OOP has been assisted by structured and modular programming--and is not by itself those things. Some of its power is simply just those disciplines.
In addition, as big as an object author and consumer I am, OOP is not the way I think. Reusability is the way I think: What have I done before that I do not want to write again? What have I written that is similar? How can I make my current task just an adapter of what has been written before. (And often: how can I sneak my behavior branch an established module in a single line?)
As a result, a number of my constructs would fail the pedestrian goal of OOP. To give you a better view: I divide code into two "domains": Highly abstract and polymorphic Library code, and the Scripting that I need to do to get the particular function that I'm required in a current project. (this is essentially what "application" means, but I don't think it would be as clear). As a result, polymorphism is mainly instrumental in providing adaptability, but the adaptation itself is whatever takes the least lines of code. My optimum system would be a library that allows scripting/adaptation at any juncture between library behavior and a set of configurations or scripts that address a particular problem. Again, if I had my druthers, configuration would be injected from the scripted domain and no library code would say "I need a properties file" by itself, unless it was a library module encapsulating the algorithm of configuration instanced in properties files. It would just know that it needs "policies" (or decisions from the application domain) in order to fulfil its function.
Thus, my ideal application contains special purpose "objects", which conform to "roles" but where classes are useless overhead--except that the classes perform the behavior which allow injectable data and behavior. So some of my Perl "objects" violate OOP analysis, because they are simply encapsulations of one-off solutions, kind of like the push-pin (expando) JavaScript objects.
I will often (later) revise a special-purpose object and push it further back into the library domain as I find that I need to write something like this again. All objects in the library domain are just on some level of the spectrum of specified behavior. Also, I arrange "data networks" where there is a Sourced type of class that simply encapsulates the behavior of accessing data either in the object itself or another source object. This helps speed my solutions immensely, but I've never seen it addressed in any duck-cat-dog-car-truck OOP primer. Also templating--especially when combined with "data networks"--immensely useful in coding solutions in a half-dozen lines or a half-day of work.
So I guess I'm saying, to the extent that you only know OOP for structuring programming, you won't be able to appreciate how much some older, sound practices or other paradigms do for you--or how things that qualify as OOP can promote mediocre adaptability. (Besides components are far more current than "objects".) Encapsulation solves many problems, but it also promotes the lack of data where you need it. The idea is to get data where you need it so that your canned behavior can realize the specifics of the problem and operate on that.
Reread some stuff on structured programming
Read some stuff on functional programming (assuming that you're not already familiar with it.)
Also it's possible that even an established, "productive" Perl team is writing ... crap. If they are not OOP programmers because they are simply writing crap code, then by all means teach them OOP and if they lack even structured programming *shove both of them down their throats* (I have a hard time considering the label "professional", here).
Take a good look at 'Perl Best Practices' by Damian Conway. It has lots of solid material in it, and you won't go far wrong taking his advice.
Be aware, though, that Getopt::Clade is only available as a placeholder package - it is vapourware, in other words.
You might want to look at what's covered in the "Modern Perl" book too:
http://onyxneon.com/books/modern_perl/
As the others say - plenty to cover without Moose.
Setting up modules/distros
Testing and TAP
Deployment with cpanm / cpan / local::lib
Important changes 5.8 5.10 vs 5.12 vs 5.14, autodie etc.
Perl programmers must know about Perl's weakly functional features, like list contexts, map, grep, etc. A little functional style makes Perl infinitely more readable.
Perl programmers must also understand Perl's traditional OO features, especially modules, bless, and tie. Make them write an object or maybe tie a Cache::Memcached object around a query or something.

Comparing Common Lisp with Gambit w.r.t their library access and object systems

I'm pretty intrigued by Gambit Scheme, in particular by its wide range of supported platforms, and its ability to put C code right in your Scheme source when needed. That said, it is a Scheme, which has fewer "batteries included" as compared to Common Lisp. Some people like coding lots of things from scratch, (a.k.a. vigorous yak-shaving) but not me!
This brings me to my two questions, geared to people who have used both Gambit and some flavor of Common Lisp:
1) Which effectively has better access to libraries? Scheme has fewer libraries than Common Lisp. However, Gambit Scheme has smoother access to C/C++ code & libraries, which far outnumber Common Lisp's libraries. In your opinion, does the smoothness of Gambit's FFI outweigh its lack of native libraries?
2) How do Scheme's object systems (e.g. TinyCLOS, Meroon) compare to Common Lisp's CLOS? If you found them lacking, what feature(s) did you miss most? Finally, how important is an object system in Lisp/Scheme in the first place? I have heard of entire lisp-based companies (e.g. ITA Software) forgoing CLOS altogether. Are objects really that optional in Lisp/Scheme? I do fear that if Gambit has no good object system, I may miss them (my programming background is purely object-oriented).
Thanks for helping an aspiring convert from C++/Python,
-- Matt
PS: Someone with more than 1500 rep, could you please create a "gambit" tag? :) Thanks Jonas!
Sure Scheme as a whole has fewer libraries in the defined standard, but any given Scheme implementation usually builds on that standard to include more "batteries included" type of functions.
Gambit, for example, uses the Snow package system which will give you access to several support libraries.
Other Schemes fare even better, having access to more (or better) support libraries. Both Racket (with PlaneT) and Chicken (with eggs) immediately come to mind.
That said, the Common Lisp is quite rich also and a large number of interesting and useful libraries are a simple asdf-install away.
As for Scheme object systems, I personally tend to favor Chicken Scheme and have taken to favoring coops. That said, there's absolutely nothing wrong with TinyCLOS. Either would serve well and don't really find anything to be lacking. Though that last statement might have more to do with the fact that I don't tend to rely on a lot of object oriented-isms when writing Scheme. Both systems in my experience tend to surface when I want to write "protocols" and then have a way of specializing on the protocol, if that makes sense.
1) I haven't used Gambit Scheme, so I cannot really tell how smooth the C/C++ integration is. But all Common Lisps I have used have fully functional C FFI:s. So the availability of C libraries is the same. It takes some work to integrate, but I assume this is the case with Gambit Scheme as well. After all, Lisp and C are different languages..? But maybe you have a different experience, I would like to learn more in that case.
You may be interested in Quicklisp, a really good new Common Lisp project - it makes it very easy to install a lot of quality libraries.
2) C++ and Python are designed to use OOP and classes as the typical means of encapsulating and structuring data. CLOS does not have this ambition at all. Instead, it provides generic functions that can be specialized for certain types of arguments - not necessarily classes. Essentially this enables OOP, but in Common Lisp, OOP is a convenient feature rather than something fundamental for getting things done.
I think CLOS is a lot more well-designed and flexible than the C++ object model - TinyCLOS should be no different in that aspect.

Language requirements for AI development [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why is Lisp used for AI?
What makes a language suitable for Artificial Intelligence development?
I've heard that LISP and Prolog are widely used in this field. What features make them suitable for AI?
Overall I would say the main thing I see about languages "preferred" for AI is that they have high order programming along with many tools for abstraction.
It is high order programming (aka functions as first class objects) that tends to be a defining characteristic of most AI languages http://en.wikipedia.org/wiki/Higher-order_programming that I can see. That article is a stub and it leaves out Prolog http://en.wikipedia.org/wiki/Prolog which allows high order "predicates".
But basically high order programming is the idea that you can pass a function around like a variable. Surprisingly a lot of the scripting languages have functions as first class objects as well. LISP/Prolog are a given as AI languages. But some of the others might be surprising. I have seen several AI books for Python. One of them is http://www.nltk.org/book. Also I have seen some for Ruby and Perl. If you study more about LISP you will recognize a lot of its features are similar to modern scripting languages. However LISP came out in 1958...so it really was ahead of its time.
There are AI libraries for Java. And in Java you can sort of hack functions as first class objects using methods on classes, it is harder/less convenient than LISP but possible. In C and C++ you have function pointers, although again they are much more of a bother than LISP.
Once you have functions as first class objects, you can program much more generically than is otherwise possible. Without functions as first class objects, you might have to construct sum(array), product(array) to perform the different operations. But with functions as first class objects you could compute accumulate(array, +) and accumulate(array, *). You could even do accumulate(array, getDataElement, operation). Since AI is so ill defined that type of flexibility is a great help. Now you can build much more generic code that is much easier to extend in ways that were not originally even conceived.
And Lambda (now finding its way all over the place) becomes a way to save typing so that you don't have to define every function. In the previous example, instead of having to make getDataElement(arrayelement) { return arrayelement.GPA } somewhere you can just say accumulate(array, lambda element: return element.GPA, +). So you don't have to pollute your namespace with tons of functions to only be called once or twice.
If you go back in time to 1958, basically your choices were LISP, Fortran, or Assembly. Compared to Fortran LISP was much more flexible (unfortunately also less efficient) and offered much better means of abstraction. In addition to functions as first class objects, it also had dynamic typing, garbage collection, etc. (stuff any scripting language has today). Now there are more choices to use as a language, although LISP benefited from being first and becoming the language that everyone happened to use for AI. Now look at Ruby/Python/Perl/JavaScript/Java/C#/and even the latest proposed standard for C you start to see features from LISP sneaking in (map/reduce, lambdas, garbage collection, etc.). LISP was way ahead of its time in the 1950's.
Even now LISP still maintains a few aces in the hole over most of the competition. The macro systems in LISP are really advanced. In C you can go and extend the language with library calls or simple macros (basically a text substitution). In LISP you can define new language elements (think your own if statement, now think your own custom language for defining GUIs). Overall LISP languages still offer ways of abstraction that the mainstream languages still haven't caught up with. Sure you can define your own custom compiler for C and add all the language constructs you want, but no one does that really. In LISP the programmer can do that easily via Macros. Also LISP is compiled and per the programming language shootout, it is more efficient than Perl, Python, and Ruby in general.
Prolog basically is a logic language made for representing facts and rules. What are expert systems but collections of rules and facts. Since it is very convenient to represent a bunch of rules in Prolog, there is an obvious synergy there with expert systems.
Now I think using LISP/Prolog for every AI problem is not a given. In fact just look at the multitude of Machine Learning/Data Mining libraries available for Java. However when you are prototyping a new system or are experimenting because you don't know what you are doing, it is way easier to do it with a scripting language than a statically typed one. LISP was the earliest languages to have all these features we take for granted. Basically there was no competition at all at first.
Also in general academia seems to like functional languages a lot. So it doesn't hurt that LISP is functional. Although now you have ML, Haskell, OCaml, etc. on that front as well (some of these languages support multiple paradigms...).
The main calling card of both Lisp and Prolog in this particular field is that they support metaprogramming concepts like lambdas. The reason that is important is that it helps when you want to roll your own programming language within a programming language, like you will commonly want to do for writing expert system rules.
To do this well in a lower-level imperative language like C, it is generally best to just create a separate compiler or language library for your new (expert system rule) language, so you can write your rules in the new language and your actions in C. This is the principle behind things like CLIPS.
The two main things you want are the ability to do experimental programming and the ability to do unconventional programming.
When you're doing AI, you by definition don't really know what you're doing. (If you did, it wouldn't be AI, would it?) This means you want a language where you can quickly try things and change them. I haven't found any language I like better than Common Lisp for that, personally.
Similarly, you're doing something not quite conventional. Prolog is already an unconventional language, and Lisp has macros that can transform the language tremendously.
What do you mean by "AI"? The field is so broad as to make this question unanswerable. What applications are you looking at?
LISP was used because it was better than FORTRAN. Prolog was used, too, but no one remembers that. This was when people believed that symbol-based approaches were the way to go, before it was understood how hard the sensing and expression layers are.
But modern "AI" (machine vision, planners, hell, Google's uncanny ability to know what you 'meant') is done in more efficient programming languages that are more sustainable for a large team to develop in. This usually means C++ these days--but it's not like anyone thinks of C++ as a good language for AI.
Hell, you can do a lot of what was called "AI" in the 70s in MATLAB. No one's ever called MATLAB "a good language for AI" before, have they?
Functional programming languages are easier to parallelise due to their stateless nature. There seems to already be a subject about it with some good answers here: Advantages of stateless programming?
As said, its also generally simpler to build programs that generate programs in LISP due to the simplicity of the language, but this is only relevant to certain areas of AI such as evolutionary computation.
Edit:
Ok, I'll try and explain a bit about why parallelism is important to AI using Symbolic AI as an example, as its probably the area of AI that I understand best. Basically its what everyone was using back in the day when LISP was invented, and the Physical Symbol Hypothesis on which it is based is more or less the same way you would go about calculating and modelling stuff in LISP code. This link explains a bit about it:
http://www.cs.st-andrews.ac.uk/~mkw/IC_Group/What_is_Symbolic_AI_full.html
So basically the idea is that you create a model of your environment, then searching through it to find a solution. One of the simplest to algorithms to implement is a breadth first search, which is an exhaustive search of all possible states. While producing an optimal result, it is usually prohibitively time consuming. One way to optimise this is by using a heuristic (A* being an example), another is to divide the work between CPUs.
Due to statelessness, in theory, any node you expand in your search could be ran in a separate thread without the complexity or overhead involved in locking shared data. In general, assuming the hardware can support it, then the more highly you can parallelise a task the faster you will get your result. An example of this could be the folding#home project, which distributes work over many GPUs to find optimal protein folding configurations (that may not have anything to do with LISP, but is relevant to parallelism).
As far as I know from LISP is that is a Functional Programming Language, and with it you are able to make "programs that make programs. I don't know if my answer suits your needs, see above links for more information.
Pattern matching constructs with instantiation (or the ability to easily construct pattern matching code) are a big plus. Pattern matching is not totally necessary to do A.I., but it can sure simplify the code for many A.I. tasks. I'm finding this also makes F# a convenient language for A.I.
Languages per se (without libraries) are suitable/comfortable for specific areas of research/investigation and/or learning/studying ("how to do the simplest things in the hardest way").
Suitability for commercial development is determined by availability of frameworks, libraries, development tools, communities of developers, adoption by companies. For ex., in internet you shall find support for any, even the most exotic issue/areas (including, of course, AI areas), for ex., in C# because it is mainstream.
BTW, what specifically is context of question? AI is so broad term.
Update:
Oooops, I really did not expect to draw attention and discussion to my answer.
Under ("how to do the simplest things in the hardest way"), I mean that studying and learning, as well as academic R&D objectives/techniques/approaches/methodology do not coincide with objectives of (commercial) development.
In student (or even academic) projects one can write tons of code which would probably require one line of code in commercial RAD (using of component/service/feature of framework or library).
Because..! oooh!
Because, there is no sense to entangle/develop any discussion without first agreeing on common definitions of terms... which are subjective and depend on context... and are not so easy to be formulate in general/abstract context.
And this is inter-disciplinary matter of whole areas of different sciences
The question is broad (philosophical) and evasively formulated... without beginning and end... having no definitive answers without of context and definitions...
Are we going to develop here some spec proposal?

Suggested content for a lunch-time "Introduction to Scala" talk

I'm going to be giving a short (30-40 mins) lunch-time talk on Scala to technical staff at my company. I'd like some suggestions for what would be the most appropriate content. Most people attending will have experience in Java and/or C# (plus various other languages).
What are the key things to cover? I'd like to give a brief introduction to the Scala syntax so that people don't feel lost when looking at code examples. I'll also cover some of the history behind the language and its designers. What would help people get the most out of the talk?
People are almost certainly coming to talk to get an answer to the question, "Why should I use Scala?" Anything you can provide to help them answer that will be valuable.
Keep the discussion of the history and the personalities behind Scala to a minimum.
A whirlwind tour of the syntax is useful, but keep it short.
Spend a good chunk of the talk demonstrating examples and comparisons to Java. Show cases where Scala shines. You should literally be running and executing code so that people get a real, hands-on feel for how things work.
Make sure to cover weaknesses, too! Provide an objective and balanced overview.
I gave a similar talk - mostly to those with a Java background. I felt that taking a piece of real Java (about 30 lines) and iteratively adding scala features worked pretty well. The 30 lines of Java eventually ended up as 6 (six!) of scala. The point being (of course) that 6 lines are more readable and maintainable than 30.
I converted the scala to line-by-line Java equivalent and then introduced:
Type inference
Option
Closures
Pattern-matching (on lists)
Type aliases
Tail recursion
I found that this segment took quite a long time because the audience were very interested in the minutiae of scala's syntax (especially around function-expressions). Before undertaking the pattern-matching bit, I had a slide explaining the various things you could use in a match.
Tough. One has to balance the new and the familiar. For instance:
Talk about traits, how they differ from interfaces and multiple inheritance. Note that most methods in all of Scala collections can actually be found on the trait Traversable, which has a single abstract method: foreach.
Speak of functions and partial functions, show map/filter/foreach, and how they make use of functions.
Talk about pattern matching -- show how unapply is used to enable representation independence, while at the same time case classes make the common case easy.
Above all AVOID any topic that might be difficult to understand quickly, or you may waste time on them. For example of great topics I wouldn't talk about: self types, variance, for-comprehensions.
Pick more topics than you have time for. Let the public steer the conversation towards the topcis they are more interested in. If anyone starts to boggle down a topic too much, say you'll be pleased to explain it in more details later, and ask if they would mind if you moved to another topic. On the other hand, if everyone seems to be picking up on one thing in particular, stay with it. Otherwise, it might feel like you want to hide something.
I gave a presentation on re-writing Java classes in Scala. It has lots of examples of Java -> Scala and (hopefully) makes the gains obvious. Feel free to borrow any content you want... presentation took 1hr 10minutes so you might want to cut some stuff out.
Presentation: http://www.colinhowe.co.uk/downloads/rewriting-java-in-scala.ppt
Video: http://skillsmatter.com/podcast/java-jee/re-writing-java-classes-in-scala-and-making-your-code-lovely
You could do worse than running through Jonas Bonér's presentation, Pragmatic Real-World Scala. Perhaps skip some advanced topics in there on different applications of traits and self-type annotations.