pdxfunc meeting: Monday, April 14, 7pm, CubeSpace -- Clojure, a concurrent Lisp on the JVM

12 views
Skip to first unread message

Igal Koshevoy

unread,
Apr 14, 2008, 12:06:34 AM4/14/08
to Igal Koshevoy
Please join us at the next meeting of pdxfunc, the Portland Functional
Programming Study Group. The group meets monthly for presentations,
demos and discussions. We welcome programmers interested in all
functional languages, and the meetings feature content for coders of all
skill levels. If interested, please subscribe to our mailing list at
http://groups.google.com/group/pdxfunc

PRESENTATION

* Patrick Logan: A Modest Introduction to Clojure: A Mostly Functional,
Concurrent Lisp on the JVM
- Abstract: Clojure is a Lisp dialect that runs on the Java Virtual
Machine. Designed as a general-purpose language, it strives to provide a
balance between functional purity and practical necessity. It includes
sophisticated concurrency support that helps it ensure clean, correct,
multithreaded designs. This talk will introduce the important aspects of
Clojure as a language on the JVM and as a dialect of Lisp, although no
experience with either will be needed to follow along. The presentation
will be primarily code-based with only a few slides. [Language homepage:
http://clojure.sourceforge.net/]
- Speaker: Patrick Logan started programming in Common Lisp in 1984 and
Scheme soon after. Tinkered with Erlang beginning in 1999, and
occasionally since then. Programmed professionally in Smalltalk off and
on since 1986, as well as C++, Java, and more, in electronics design and
manufacturing, financial systems, insurance, and peer-to-peer conference
systems. Written less than 500 lines of Clojure to date, but the
language is luring him in.

REMAINDER

The rest of the meeting will be open for participants to ask questions
and discuss projects, technical challenges, recent developments, etc.
The group's members have a wide range of experiences, so there's never a
shortage of interesting discussions.

-igal

PS: I'm incredibly sorry for posting this so late. I actually posted the
message Thursday night, but made an error that caused it to bounce, then
my spam filter ate the bounces, and thus I didn't realize there was a
problem until now. I'm sorry Patrick. :(

Igal Koshevoy

unread,
Apr 14, 2008, 12:40:38 AM4/14/08
to pdxfunc
I'm afraid I'm sick again and likely won't be able to make the
meeting, which is really disappointing because I was rather looking
forward to it.

Anyone: It'd be awesome if someone could post a text summary, or audio
or video recording from the presentations.

Patrick and Adam: Can you please post slides and code after you're
done?

Phil and Bart: Can you please handle MC duties again?

Thanks. I'm really sorry. :(

-igal

John Watson

unread,
Apr 14, 2008, 1:22:21 AM4/14/08
to pdx...@googlegroups.com
Wow.  I wish I could go to this, also, but the notice is too short for me.  I'd love some a/v recording too, if possible.

John

Amy K. Farrell

unread,
Apr 22, 2008, 12:41:24 AM4/22/08
to pdx...@googlegroups.com
I thought I'd make an attempt at contributing something to the group
by taking notes last week. Here's my attempt at capturing some of the
content of the presentation and discussion. At least the "upcoming
events" are accurate, as they were easy to verify online!

- Amy

========================================

Portland Functional Programming Study Group, 2008-04-14

The meeting started off with some informal chat and reminders of
upcoming events that may be of interest (URLs added post hoc):

Innotech at the Convention Center (now past)
Erlounge, an Erlang gathering in Seattle 04/25 @ 6:30 (Kevin later
posted details to the list - thanks)
LinuxFest Northwest, April 26-27: http://linuxfestnorthwest.org/
BarCamp coming up on May 2,3,4: http://barcamp.org/BarCampPortland
DrupalCampPDX is on May 10: http://groups.drupal.org/node/9748

========================================

Topic: "A Modest Introduction to Clojure"
Speaker: Patrick Logan

Patrick gave us an introduction to Clojure in a live-demo
fashion. This made for an effective mix of presentation and
discussion.

Background from the abstract for this talk:

Abstract: Clojure is a Lisp dialect that runs on the Java Virtual
Machine. Designed as a general-purpose language, it strives to
provide a balance between functional purity and practical
necessity. It includes sophisticated concurrency support that helps
it ensure clean, correct, multithreaded designs. This talk will
introduce the important aspects of Clojure as a language on the JVM
and as a dialect of Lisp, although no experience with either will
be needed to follow along. The presentation will be primarily
code-based with only a few slides. [Language homepage:
http://clojure.sourceforge.net/]

Speaker: Patrick Logan started programming in Common Lisp in 1984


and Scheme soon after. Tinkered with Erlang beginning in 1999, and
occasionally since then. Programmed professionally in Smalltalk off
and on since 1986, as well as C++, Java, and more, in electronics
design and manufacturing, financial systems, insurance, and
peer-to-peer conference systems. Written less than 500 lines of
Clojure to date, but the language is luring him in.

Your notetaker last used Scheme 20+ years ago for a class, and can
claim only to know Java when she sees it, so may well have
misconstrued a thing or two along the way. Errors in the notes that
follow are all mine. -akf

What makes Clojure a LISP?

* Uses s-expressions as its syntax
* macros
* has readtables like Common LISP

Some quirks and features of Clojure:

* no car! "first"
* "second", "rest", "frest", "rfirst", does not go on indefinitely
like cdadr etc.
* Uses square brackets a bit differently than scheme -- denotes a vector.
* Also for binding variables, e.g. (let [a 1 b 3] (+ a b))
* can use commas as whitespace...
* type predicates (vector?, class, seq?)
* cycle -- lazy list
* has multimethods

Mostly functional, moreso even than Scheme. Lists, vectors, hashes are
all persistent and immutable. To define a mutable variable, you can
use def. Creates a mutable variable that is thread-local. e.g.,

(let [a 10 b 5] (def ccc 4) (* a b))
ccc
=> 4
(def x 4)
x
=> 4

(def box (var x))

Boxes are mutable (thread-local or shared across threads).

Some quirks: map syntax, treatment of nil:

(= (cons 1 ()) (cons 1 nil))
=> true
(= () nil)
=> false

... it's unclear whether this is by design, or a bug.

Recursion: running on JVM, the language is not as recursive as you
might like. Uses Java call stack, not tail-recursive.

(defn fact [n] (if (== n 1) 1 (* n (fact (-n 1 ))))) (fact 3)

Anonymous function of 3 args:

(#(* 2 %1 %2 %3) 20 30 40)
=> 48000
(#(* 2 %2 %3) 20 30 40)
=> 2400

(Adam Jones interjected that the bootstrapping code for defn is
interesting to read.)

Metadata - readtable ^# -- next form is the metadata; it will be
associated with following form.

(def vec #^{:a 2 :b 6} [1 2 3])
(meta vec)
=> {:b 6 :a 2}

Other special syntax: recur, loop

(defn fact [n]
(loop [result 1, n n]
(if (== n 1)
result
(recur (* n result) (-n 1)))))

recur -> back to loop with new binding. Use must be tail-recursive.

(defn fact
([n] (fact n 1))
([n result] (if (== n 1)
result
(recur (* n result) (-n 1)))))


Can freely access classes in Java:

(import '(java.swing....


Concurrency: vars are thread-local boxes to store mutable values.

A ref is like a var, but can be seen across threads:

(def r (ref 3))
@r
=> 3

(ref-set r 5)
=> gives us an exception, no transaction running

(dosync (ref-set r 5))
@r
=> 5

commute -- if you know you are applying a commutative operation
(transaction order doesn't matter), you can use a commute form, and
the change will be applied at commit time to the current value. It's
up to you to use this wisely.

=============== BREAK ===============

Adam Jones shared some of his experiences working with Java and
Clojure on a game implementation.

* importing classes
* creating objects
* method calls (. temp-text (getText))

Clojure supports implementing interfaces from Java with a proxy
syntax:

(proxy [Class and Interfaces] [Superclass constructor args]
f => (name [params*] body) or
(name ([params*] body) ([params+] body) ...)

There are limitations to this; Adam doesn't generally use it and
writes what he needs in Java instead. You cannot call protected
methods when you do this, and don't get some exceptions until runtime.

The Clojure developer is moving quickly. Code is changing frequently
and mostly not well-documented.

Appeal of Clojure: Adam was looking for a LISP on the JVM. It's much
faster than Jython, very small.

Top-level definitions *are* redefinable. It's more immutable by
convention.

Patrick noted that transaction conflicts are only handled at the box
level. If the box points at a Java data structure, you can change the
Java data structure and the transactional machinery won't know. So
it's not really safe to replay transactions when Java data structures
are involved.

Trying to move mutable state and things that need speed into Java.

Any time you eval you get a generic Java object. This can lead to
doing a lot of casting.

All the Clojure datatypes implement the Iterable interface, so Java
code can consume them.


========================================

Patrick Logan

unread,
Apr 22, 2008, 1:29:30 AM4/22/08
to pdx...@googlegroups.com
Great notes Amy. Thanks very much!

Igal Koshevoy

unread,
Apr 24, 2008, 12:00:57 PM4/24/08
to pdx...@googlegroups.com
Amy,

Thanks for taking those excellent notes and posting them. I look forward
to going through these in detail with a REPL and manual to catch up on
what I missed at the meeting. :)

-igal

Reply all
Reply to author
Forward
0 new messages