Full Disclojure - Murray State University
Download
Report
Transcript Full Disclojure - Murray State University
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: lists, vectors, array-maps, sets.
Count
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 datastructure 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?