A review of the Clojure Programming Language FULL























- Slides: 23

A review of the Clojure Programming Language FULL DISCLOJURE

OUTLINING CLOJURE � Background – who, when, and why. � Overview of Language Design � Names, Binding and Scope � Data Structures � Expression and Assignment � Control Structures � Subprograms � Abstraction/Encapsulation

OUTLINING CLOJURE (CONT’…) � Object Orientation � Concurrency � Exceptions and Events � Evaluation of Clojure � Readability � Writability � Reliability � Cost � Discussion

CLOJURE’S STORY � Author Rich Hickey first released in 2007. � Essentially a unified JVM-based LISP. � Supposed to make programming, specifically with regard to concurrency, easier. � Aims at combatting the perceived overuse of object-orientation and its implications. � Pragmatism trumps idealism: Not purely functional, OO borrowed from where useful.

NAMES, BINDINGS, AND SCOPE � Slightly different naming scheme � As usual case-sensitive and no leading numeric � Alphanumerics, “+”, “-”, “*”, “/”, “!”, “? ”, “_” � Everything is a symbol (details later) � Scope is lexical with ‘let’, dynamic with ‘bind’. � Var is Clojure’s variable (but not really). � Keywords always evaluate to themselves.

DATA STRUCTURES � Data structures are immutable (no changes). � “Nil” is Java Null, representing all of nothing. � False is either “false” or “nil”, all else is true. � Has Java primitives plus the Ratio Type. � Operators don’t autopromote overflowing values, but they have complements that do. � Coercion is widening (as with Java).

DATA STRUCTURES (CONT’…) � Collections: � Count lists, vectors, array-maps, sets. gets the collection size � Conj adds to the collection � Seq sequences the collection according to its type (different behaviors, but all use it) � Supports set operations and some relations.

EXPRESSION AND ASSIGNMENT � Forms are Clojure Expressions. � Parenthetical prefix notation using forms. � Leftmost form is the function, while the remainder are arguments of the function. � No declarations – Clojure is Dynamic � No interpreter required: items are examined, and if needed compiled and evaluated.

EXPRESSION AND ASSIGNMENT (CONT’…) � Evaluation resolves literals and keywords to themselves, and symbols to their value. � Symbol resolution is path-dependent � Namespace-qualified gives its global value � Package-qualified symbol gives it Java-class � Special forms get applied with their rules. � Class-mapping, local binding, var, are checked. � Nonexistence will generate an error.

EXPRESSION AND ASSIGNMENT (CONT’…) � The form comprises everything. � Literals are forms that are their own values. � Symbols are the next lowest, being nonliterals and nonsyntactic characters. � Composites are defined by enclosing brackets and represent vectors, maps, or lists. � Special forms are composites whose definitions are built directly into Clojure. � Macros are used to extend code internally.

CONTROL STRUCTURES � “do” executes a sequence of forms in order. � “if” takes the comparison, the true-return, and the optional else-return as parameters. � “if-not” is a macro inverting the “if” special form. � “when” is a macro of “if” with an implicit “do”. � “when-not” is an inversion of “when”. � “cond” approximates if-elseif structure. � “condp” approximates the switch structure.

CONTROL STRUCTURES (CONT’…) � There are no loops in Clojure. � Recursion is the only way to iterate. � A function call containing a control statement allows recursion to emulate typical looping. � Unbounded or infinite loops are achievable using recur to eliminate memory growth, but it must be explicitly called.

SUBPROGRAMS � Clojure programs are built up like trees from functions as nodes and values as leaves. � Invites too-clever coding and the associated inscrutable maladies arising therefrom. � All functions are first-class objects, so they can appear as values to other functions. � Functions needn’t be predefined for use. � OO behavior can be achieved with layers.

ABSTRACTION/ENCAPSULATION � Record, Protocol, and Type enable custom data-structure definition. � Records assign a type to a map or hash-map using “defrecord” to specify the type. � Protocols resemble Java interfaces, and are implemented using “extends”. � Types are specified with “deftype” which is essentially “defrecord” sans implementation.

ABSTRACTION/ENCAPSULATION (CONT’…) � Macros take unevaluated arguments and instead of values return forms. � This allows direct manipulation of code within the program, by the program itself. � Since Clojure is homoiconic (i. e. data and code have identical structuring) , this enables the powerful metaprogramming for which LISP is known.

OBJECT ORIENTATION � Clojure is Anti-OOP, in that it attempts to deobjectify programming. � Polymorphism is maintained, but decoupled from the state-and-behavior object model. � The desirable OO tools are inherently available, and object-equivalent structures can be synthesized as needed. � Ref and Agent allow for identity modeling.

CONCURRENCY � Clojure’s mutable state is rarely-needed evil. � It uses Software Transactional Memory (STM) to eliminate concurrency issues. � Locks, semaphores, and mutexes aren’t studied, they are automatic to the language. � Concurrent operations are given snapshots, each does its work, and then changes are merged back together, retrying as needed.

CONCURRENCY (CONT’…) � Reference types: Ref, Agent, Atom, and Var � A “ref” requires interaction within transaction. � An “agent” value is handed to a function, and the return is then assigned to the agent. � An “atom” is based on java. util. atomic, the classes aren’t race or locking sensitive. � A “var” is a global variable used for tracking runtime settings and the like.

CONCURRENCY (CONT’…) � Multimethods are Clojure’s prime polymorphism construct. � The idea is that a function designator calls the appropriate function based on the received value. � The equivalent of normal object behavior would have the value equal “this”. � Implementation inheritance is unsupported.

EXCEPTIONS AND EVENTS � Java requires explicit exception handling, and its design works down into the JVM. � Clojure doesn’t require checked exception handling by the programmer, but must deal with the JVM requirements. � To cope, all functions throw root (Runtime) Exception, and the program passes exceptions out from the caller.

EXCEPTIONS AND EVENTS (CONT’…) � Naturally, Java’s event-handlers were designed to deal with mutable state. � Dealing with this uses dynamic bindings. � Since the handlers are typically singlethreaded, this rarely threatens concurrency. � Several GUI frameworks for Clojure exist, perhaps most notable Seesaw.

EVALUATING CLOJURE � Readability benefits from the syntactic sugar, but suffers from the unfamiliar LISP style. � Writability also benefits from brevity, but again the alien qualities hinder this as well. � Reliability is benefitted by the JVM, pace of development, and Clojure’s general ideals. � Cost is lessened by having the JVM, but the learning curve can be a training obstacle.

DISCUSSION � Thank you for your time, patience, or interest (whichever you happen to have). � Coming up next: An implementation of a boundary-free “Game of Life”. � Before we go to code, any questions first?