Like this presentation? Why not share!

# Conjfeatures

## on Mar 08, 2011

• 239 views

### Views

Total Views
239
Views on SlideShare
239
Embed Views
0

Likes
1
9
0

No embeds

### Report content

• Comment goes here.
Are you sure you want to
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n
• \n

## ConjfeaturesPresentation Transcript

• New Features in Clojure Rich Hickey
• Overview• Uniﬁed primitive semantics• Map key equality• Improved interaction between dynamic binding and thread pools• Explicitly dynamic vars• Primitive support in fns• This is all work-in-progress!
• Objective - Unify Semantics• Unify primitive and boxed integer semantics • Currently, boxed integer arithmetic promotes to bigint as needed • Primitive arithmetic throws on overﬂow • Means that you always have to be explicit about primitives • difﬁculty with representation choices • incidental boxing changes meaning
• Objective - Make Fast Numerics Simple• Would like to have literal numbers be used as primitives when possible • Ditto primitive method returns• Coercion and primitive ops currently for experts only • Easy to fail to optimize
• Uniﬁed Integer Semantics• The semantics of primitive longs, plus throw on overﬂow • This is the only semantic that works for both boxed and primitive• For bigint arithmetic, specify bigint operands • new literal bigint format: 42N• Polymorphic boxed numeric tower still in place• bigints now contagious, no more auto- reductions
• Numeric Features• Literal numbers are now treated implicitly as primitives • Locals known to be numbers are automatically coerced to long or double• More automatic conversions • int matches long, ﬂoat matches double• Consistent canonic integer boxing • If ﬁts in long, is Long
• Numeric Features• longs also match ints, and doubles match ﬂoats • long->int is checked• Can’t force boxed representation from primitive coercion: • was always a bug to presume otherwise • (class (int 42)) => Long • ditto boxed values coming from arrays of primitives, and primitive returns from interop
• Auto-promotion• No longer the default• Still available explicitly• ’ is now a constituent character (like #)• +, -, *, inc, dec do auto-promotion • never return primitives • Unless you need to work with arbitrary- precision integers where BigInt contagion is insufﬁcient, there is no reason to use them.
• Objective - Align Map Keys and Numeric =• Users frustrated when insert with one key representation, lookup fails with another• Use (type ﬂexible) equivalence for map = • but narrow equiv, only same category numbers are = • so ﬂoats not = to integers • but == still available for that• new clojure.lang.BigInt class
• Map Key Equality• Hash maps and sets now use = for keys • this will make maps and sets unify 42 and 42N, since using =• Will still use stricter .equals when calling through java.util interfaces• Not there yet • this will require renaming Associative.containsKey, since semantics will now differ
• Objective - Make Binding Work with Threads • When work is sent to thread-pool threads, e.g. via agent sends or future calls, the work isnt done with the same binding set as the invocation (without manual effort) • Yet that is often the expectation/desire • Makes transparent parallelization difﬁcult • Current tools for propagating bindings are expensive
• Binding Issues• Intended to be used within one thread• Don’t support a notion of task or unit of work crossing threads• Unsafe if used between threads • thus, must be copied • i.e., new bindings created for subtask thread
• Binding Conveyance• Bindings are now automatically shared with threads used for future calls and agent sends • and anything built on them, e.g. pmap• This reroots the binding frame for thread pool thread prior to your work fn running • so bindings in work fn ‘win’• Just works
• Binding and Scopes• Much of this work driven by needs of resource scopes • Natural ﬁt for binding • But need same notion of task tree • and without conveyance, would have same thread problems/surprises as bindings• Scopes work can now proceed
• Objective - Pay for What You Use• All defs currently create fully dynamically rebindable vars• Incur cost for every access • Is it dynamically bound? • Is it unbound? • What’s the current value• Yet most vars (defns) have rarely-changing values, never dynamically bound
• Why Top Level Vars?• Traditional context-bound dynamic variables, like *out* et al• Dynamically bound fns can be used for error handling• Replace fns with ﬁxed versions • Doesn’t require rebinding• Mutable globals
• Be Explicit about Dynamic Intent• Change default semantic from dynamically rebindable to not• Must declare vars dynamic using • ^:dynamic metadata • or .setDynamic on manually created Vars• Better for consumers• Enables signiﬁcant optimizations
• Metadata Features• New ^:keyword metadata • turns into ^{:keyword true}• Metadata stacks - ^:dynamic ^:private foo • Merges rather than replaces • same as ^{:dynamic true :private true} foo
• Remove Overhead• Remove binding check from access to non- dynamics• Remove bound check from normal access • instead return Unbound object • has the var as ﬁeld, prints in toString • implements IFn and throws on any invoke, with good message
• Presume Stability• Replace via defn to ﬁx bugs case still remains • infrequent, but would like to avoid pain of static (i.e., re-eval of caller code)• Minimize overhead • cache var values in fn • global var rev, inc on any var alteration • check rev on fn entry and reload vars if changed • else use cached values
• Objective - SupportPrimitive Args/Returns• Clojure supports primitive arithmetic locally, and primitives in deftype/defrecord • But not in fn arguments or returns • Means you can’t break up your logic, or write helper functions, without introducing boxing
• Issues• fn is speciﬁed by an interface (IFn), taking and returning Objects • fns must still satisfy that interface• How will callers know about primitive params/return, and how to invoke? • Support ^long and ^double type hints on args/return
• IFn\$LOD...• New set of single-method nested IFn interfaces • Corresponding to all combinations of Object/long/double, to arity 4• Compiler will compile invokePrim methods in addition to IFn virtual invoke methods• When compiling direct invocation of prim fn, compiler will look at arglists metadata and make call to invokePrim method• var still contains IFn object for HOFs etc
• More Features• ^long and ^double hints supported on args• hint for return goes on arg vector • e.g. (defn foo ^long [x] ...) • so supports multi-arity with varied returns• Other reference type hints allowed as well • Just for hints, not enforced
• Future Fns• Primitive-taking fn interfaces open door to non-boxing HOFs• One more step to dynamically typed, yet internally primitive, map and reduce • When combined with collections of primitives • and chunked seqs
• Summary• New features enable much faster code• Uniﬁed semantics reduce complexity • all features are still available • auto-promotion is explicit • dynamic binding is explicit• Optimization more automatic, less work, less subtle• Pave the way for scopes and primitive HOFs