Yes, each platform defines their own platform feature so it wouldn't be too 
hard to change the specified platform in the fork. However the key here is that 
the conditional occurs at read time, so you need to ensure that compilation 
happens with this platform if aot is involved. Maybe that's obvious.

The existing code in Clojure will not fail in unknown features so you would be 
able to read the same code in Clojure or Android.

I'll ask Rich about a preferred feature name.



> On Apr 5, 2015, at 5:44 PM, Alexander Yakushev <a...@bytopia.org> wrote:
> 
> Well, I must say I'm even more ignorant in how the feature expansions are 
> implemented. Is the feature a thing that each implementation defines 
> separately? If so, then it will be easy to set our fork's feature as :clja, 
> or whatever else. My request to you would then be: can you please include 
> :clja into the "spec", in the list of available features? What I ask for is 
> sort of semi-official confirmation that Clojure-Android has its own feature, 
> so that we would have easier time to include Android-specific code into the 
> libraries that will become cross-platform after 1.7 goes live.
> 
> Best regards,
> Alex
> 
>> On Monday, April 6, 2015 at 12:34:04 AM UTC+3, Alex Miller wrote:
>> The reader can be invoked programmatically with any feature set you like 
>> now. We did not plan to allow custom features for 1.7.
>> 
>> I'm not sure what it would mean to "add" an android feature? I'll plead 
>> ignorance in not knowing how the Clojure 
>> Android stuff works or where a feature indicating Android could be set 
>> without support for custom features. Do you currently fork to support 
>> Android?
>> 
>> 
>> 
>> On Apr 5, 2015, at 1:44 PM, Alexander Yakushev <al...@bytopia.org> wrote:
>> 
>> Hello Alex,
>> 
>> As I've understood from the dev.clojure.org page, additional features and 
>> feature combinations will become available later. Can we please get 
>> :clj/android (or :clja) still in 1.7? If so, what has to be done by me or 
>> Daniel to make it happen?
>> 
>> Thanks!
>> 
>> On Tuesday, March 31, 2015 at 7:50:27 PM UTC+3, Alex Miller wrote:
>> Clojure 1.7.0-alpha6 is now available.
>> 
>> Try it via
>> - Download: https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-alpha6/
>> - Leiningen: [org.clojure/clojure "1.7.0-alpha6"]
>> 
>> Regression fixes from previous alphas (and one from 1.6):
>> 
>> 1) CLJ-1544 was rolled back and will be investigated for a future release.
>> 2) CLJ-1637 fixed regression with vec on MapEntry 
>> 3) CLJ-1663 fixed regression in classloader (affected Cursive)
>> 4) CLJ-1638 fixed regression with removed PersistentVector.create(List) 
>> method
>> 5) CLJ-1681 fixed regression in 1.6 with NPE on reflection warning for 
>> literal nil arg
>> 6) CLJ-1604 fixed problem with AOT and shadowing clojure.core symbols that 
>> prevented update
>> 
>> Some highlights new in alpha6:
>> 
>> ## Transducer-related changes:
>> 
>> The LazyTransformer introduced to create lazy transforming sequences has 
>> been 
>> replaced with a TransformingIterator. This was done to simplify the code
>> around transformations and to make certain use cases around eduction more 
>> efficient.
>> 
>> ## Faster reduce, iterator, and sequence paths
>> 
>> A lot of work has been done across a set of tickets to improve the ability of
>> collections to provide more efficient reduce or iterator performance, and 
>> also to
>> make common sequence generators create faster sequence and reduce paths. You
>> should see significant performance in many reduce-related paths (this 
>> includes 
>> reduce, transduce, into, and anything else built on reduce). 
>> 
>> Many of those changes also have beneficial sequence performance, so you may 
>> see
>> some benefits even in code that does not use transducers.
>> 
>> * Most uses of SeqIterator have now been replaced with iterators that 
>> directly walk
>> the underlying source for improved efficiency. This includes maps, sets, 
>> records, etc.
>> * repeat - now returns a faster sequence with a fast reduce path
>> * cycle - now returns a faster sequence with a fast reduce path
>> * iterate - now returns a faster sequence with a fast reduce path
>> * range - (did not quite make it in, but coming soon...)
>> * keys - iterates directly over the keys of a map, without seq or MapEntry 
>> allocation
>> * vals - iterates directly over the vals of a map, without seq or MapEntry 
>> allocation
>> * iterator-seq - now creates a chunked sequence when previously it was 
>> unchunked
>> * vec and set - were not changed in this release but were set up in a 
>> previous alpha
>>   to take advantage of the reduce and iterator changes above
>> 
>> ## Reader conditionals
>> 
>> Reader Conditionals is a new capability to support portable code that
>> can run on multiple Clojure platforms with only small changes. In
>> particular, this feature aims to support the increasingly common case
>> of libraries targeting both Clojure and ClojureScript.
>> 
>> Code intended to be common across multiple platforms should use a new
>> supported file extension: ".cljc". When requested to load a namespace,
>> the platform-specific file extension (.clj, .cljs) will be checked
>> prior to .cljc.
>> 
>> A new reader form can be used to specify "reader conditional" code in
>> cljc files (and *only* cljc files). Each platform defines a feature
>> identifying the platform (:clj, :cljs, :cljr). The reader conditional
>> specifies code that is read conditionally based on the feature/
>> 
>> Form #? takes a list of alternating feature and expression. These are
>> checked like cond and the selected expression is read and returned. Other
>> branches are unread. If no branch is selected, the reader reads nothing
>> (not nil, but literally as if reading ""). An optional ":default" branch
>> can be used as a fallthrough.
>> 
>> Reader conditional with 2 features and a default:
>> 
>>      #?(:clj     Double/NaN
>>         :cljs    js/NaN
>>         :default nil)
>> 
>> There is also a reader conditional splicing form. The evaluated expression
>> should be sequential and will be spliced into the surrounded code, similar
>> to unqoute-splicing.
>> 
>> For example:
>> 
>>    [1 2 #?@(:clj [3 4] :cljs [5 6])]
>> 
>> This form would read as [1 2 3 4] on Clojure, [1 2 5 6] on ClojureScript,
>> and [1 2] on any other platform.
>> 
>> Additionally, the reader can now be invoked with options for the features
>> to use and how to interpret reader conditionals. By default, reader 
>> conditionals
>> are not allowed, but that can be turned on, or a "preserve" mode can be used 
>> to
>> preserve all branches (most likely useful for tooling or source transforms).
>> 
>> In the preserve mode, the reader conditional itself and any tagged literals
>> within the unselected branches are returned as tagged literal data.
>> 
>> For more information, see:
>> http://dev.clojure.org/display/design/Reader+Conditionals
>> 
>> Two important side notes:
>> - Clojure dependencies have been updated and you must re-run antsetup.sh if 
>> you
>> build Clojure locally with ant.
>> - The equivalent ClojureScript support for reader conditionals is not yet 
>> available
>> but is a top priority to release as soon as possible... stay tuned.
>> 
>> ## Printing as data
>> 
>> There have been enhancements in how the REPL prints values without a
>> print-method, specifically Throwable and the fallthrough Object case.
>> Both cases now print in a tagged literal data form that can be read
>> by the reader.
>> 
>> Unhandled objects print with the class, hash code, and toString:
>> 
>>      user=> *ns*
>>      #object[clojure.lang.Namespace 0x55aa628 "user"]
>> 
>> Thrown exceptions will still be printed in the normal way by the default
>> REPL but printing them to a stream will show a different form:
>> 
>>      user=> (/ 1 0)
>>      ArithmeticException Divide by zero  clojure.lang.Numbers.divide 
>> (Numbers.java:158)
>>      user=> (println *e)
>>      #error{:cause Divide by zero,
>>                 :via [{:type java.lang.ArithmeticException,
>>                            :message Divide by zero,
>>                                :at [clojure.lang.Numbers divide Numbers.java 
>> 158]}],
>>                 :trace
>>                   [[clojure.lang.Numbers divide Numbers.java 158]
>>                        [clojure.lang.Numbers divide Numbers.java 3808]
>>                        [user$eval5 invoke NO_SOURCE_FILE 3]
>>                        ;; elided ...
>>                        ]]}
>>                        
>> For all changes new in alpha6, see the issues marked "(alpha6)" in the
>> full changes below.
>> 
>> ------------------------------------------------------------
>> Clojure 1.7.0-alpha6 has the following updates since 1.6.0:
>> 
>> ## 1 New and Improved Features
>> 
>> ### 1.1 Transducers
>> 
>> Transducers is a new way to decouple algorithmic transformations from their
>> application in different contexts. Transducers are functions that transform
>> reducing functions to build up a "recipe" for transformation.
>> 
>> Also see: http://clojure.org/transducers
>> 
>> Many existing sequence functions now have a new arity (one fewer argument
>> than before). This arity will return a transducer that represents the same
>> logic but is independent of lazy sequence processing. Functions included are:
>> 
>> * conj (conjs to [])
>> * map
>> * mapcat
>> * filter
>> * remove
>> * take
>> * take-while
>> * drop
>> * drop-while
>> * take-nth
>> * replace
>> * partition-by
>> * partition-all
>> * keep
>> * keep-indexed
>> * map-indexed
>> * distinct
>> * interpose
>> 
>> Additionally some new transducer functions have been added:
>> 
>> * cat - concatenates the contents of each input
>> * dedupe - removes consecutive duplicated values
>> * random-sample - returns items from coll with random probability
>> 
>> And this function can be used to make completing transforms:
>> 
>> * completing
>> 
>> There are also several new or modified functions that can be used to apply
>> transducers in different ways:
>> 
>> * sequence - takes a transformation and a coll and produces a lazy seq
>> * transduce - reduce with a transformation (eager)
>> * eduction - returns a reducible/iterable of applications of the transducer 
>> to items in coll. Applications are re-performed with every reduce/iterator.
>> * run! - run the transformation for side effects on the collection
>> 
>> There have been a number of internal changes to support transducers:
>> 
>> * volatiles - there are a new set of functions (volatile!, vswap!, vreset!, 
>> volatile?) to create and use volatile "boxes" to hold state in stateful 
>> transducers. Volatiles are faster than atoms but give up atomicity 
>> guarantees so should only be used with thread isolation.
>> * array iterators - added support for iterators over arrays
>> 
>> Some related issues addressed during development:
>> * [CLJ-1511](http://dev.clojure.org/jira/browse/CLJ-1511)
>> * [CLJ-1497](http://dev.clojure.org/jira/browse/CLJ-1497)
>> * [CLJ-1549](http://dev.clojure.org/jira/browse/CLJ-1549)
>> * [CLJ-1537](http://dev.clojure.org/jira/browse/CLJ-1537)
>> * [CLJ-1554](http://dev.clojure.org/jira/browse/CLJ-1554)
>> * [CLJ-1601](http://dev.clojure.org/jira/browse/CLJ-1601)
>> * [CLJ-1606](http://dev.clojure.org/jira/browse/CLJ-1606)
>> * [CLJ-1621](http://dev.clojure.org/jira/browse/CLJ-1621)
>> * [CLJ-1600](http://dev.clojure.org/jira/browse/CLJ-1600)
>> * [CLJ-1635](http://dev.clojure.org/jira/browse/CLJ-1635) (alpha6)
>> * [CLJ-1683](http://dev.clojure.org/jira/browse/CLJ-1683) (alpha6)
>> * [CLJ-1669](http://dev.clojure.org/jira/browse/CLJ-1669) (alpha6)
>> 
>> ### 1.2 Reader Conditionals (alpha6)
>> 
>> Reader Conditionals is a new capability to support portable code that
>> can run on multiple Clojure platforms with only small changes. In
>> particular, this feature aims to support the increasingly common case
>> of libraries targeting both Clojure and ClojureScript.
>> 
>> Code intended to be common across multiple platforms should use a new
>> supported file extension: ".cljc". When requested to load a namespace,
>> the platform-specific file extension (.clj, .cljs) will be checked
>> prior to .cljc.
>> 
>> A new reader form can be used to specify "reader conditional" code in
>> cljc files (and *only* cljc files). Each platform defines a feature
>> identifying the platform (:clj, :cljs, :cljr). The reader conditional
>> specifies code that is read conditionally based on the feature/
>> 
>> Form #? takes a list of alternating feature and expression. These are
>> checked like cond and the selected expression is read and returned. Other
>> branches are unread. If no branch is selected, the reader reads nothing
>> (not nil, but literally as if reading ""). An optional ":default" branch
>> can be used as a fallthrough.
>> 
>> Reader conditional with 2 features and a default:
>> 
>>      #?(:clj     Double/NaN
>>         :cljs    js/NaN
>>         :default nil)
>> 
>> There is also a reader conditional splicing form. The evaluated expression
>> should be sequential and will be spliced into the surrounded code, similar
>> to unqoute-splicing.
>> 
>> For example:
>> 
>>    [1 2 #?@(:clj [3 4] :cljs [5 6])]
>> 
>> This form would read as [1 2 3 4] on Clojure, [1 2 5 6] on ClojureScript,
>> and [1 2] on any other platform.
>> 
>> Additionally, the reader can now be invoked with options for the features
>> to use and how to interpret reader conditionals. By default, reader 
>> conditionals
>> are not allowed, but that can be turned on, or a "preserve" mode can be used 
>> to
>> preserve all branches (most likely useful for tooling or source transforms).
>> 
>> In the preserve mode, the reader conditional itself and any tagged literals
>> within the unselected branches are returned as tagged literal data.
>> 
>> For more information, see:
>> http://dev.clojure.org/display/design/Reader+Conditionals
>> 
>> * [CLJ-1424](http://dev.clojure.org/jira/browse/CLJ-1424)
>> 
>> ### 1.3 Keyword and Symbol Construction
>> 
>> In response to issues raised in 
>> [CLJ-1439](http://dev.clojure.org/jira/browse/CLJ-1439),
>> several changes have been made in symbol and keyword construction:
>> 
>> 1) The main bottleneck in construction of symbols (which also occurs inside 
>> keywords) was
>> interning of the name and namespace strings. This interning has been 
>> removed, resulting
>> in a performance increase.
>> 
>> 2) Keywords are cached and keyword construction includes a cache check. A 
>> change was made
>> to only clear the cache reference queue when there is a cache miss.
>> 
>> ### 1.4 Warn on Boxed Math
>> 
>> One source of performance issues is the (unintended) use of arithmetic 
>> operations on
>> boxed numbers. To make detecting the presence of boxed math easier, a 
>> warning will now
>> be emitted about boxed math if \*unchecked-math* is set to :warn-on-boxed 
>> (any truthy
>> value will enable unchecked-math, only this specific value enables the 
>> warning).
>> 
>> Example use:
>> 
>>     user> (defn plus-2 [x] (+ x 2))  ;; no warning, but boxed
>>      #'user/plus-2
>>     user> (set! *unchecked-math* :warn-on-boxed)
>>      true
>>     user> (defn plus-2 [x] (+ x 2)) ;; now we see a warning
>>     Boxed math warning, NO_SOURCE_PATH:10:18 - call: public static 
>> java.lang.Number
>>      clojure.lang.Numbers.unchecked_add(java.lang.Object,long).
>>     #'user/plus-2
>>      user> (defn plus-2 [^long x] (+ x 2)) ;; use a hint to avoid boxing
>>      #'user/plus-2
>> 
>> * [CLJ-1325](http://dev.clojure.org/jira/browse/CLJ-1325)
>> * [CLJ-1535](http://dev.clojure.org/jira/browse/CLJ-1535)
>> * [CLJ-1642](http://dev.clojure.org/jira/browse/CLJ-1642) (alpha6)
>> 
>> ### 1.5 update - like update-in for first level
>> 
>> `update` is a new function that is like update-in specifically for 
>> first-level keys:
>> 
>>     (update m k f args...)
>> 
>> Example use:
>> 
>>     user> (update {:a 1} :a inc)
>>      {:a 2}
>>      user> (update {:a 1} :a + 2)
>>      {:a 3}
>>      user> (update {} :a identity)  ;; missing returns nil
>>      {:a nil}
>> 
>> * [CLJ-1251](http://dev.clojure.org/jira/browse/CLJ-1251)
>> 
>> ### 1.6 Faster reduce and iterator paths (alpha6)
>> 
>> Several important Clojure functions now return sequences that also
>> contain fast reduce() (or in some cases iterator()) paths. In many
>> cases, the new implementations are also faster for lazy sequences
>> 
>> * repeat - now implements IReduce
>> * cycle - implements IReduceInit
>> * iterate - implements IReduceInit
>> * range - implements IReduce, specialized case handles common case of all 
>> longs
>> * keys - iterates directly over the keys of a map, without seq or MapEntry 
>> allocation
>> * vals - iterates directly over the vals of a map, without seq or MapEntry 
>> allocation
>> * iterator-seq - creates a chunked sequence when previously it was unchunked
>> 
>> Additionally, hash-maps and hash-sets now provide iterators that walk
>> the data structure directly rather than via a sequence.
>> 
>> A new interface (IMapIterable) for direct key and val iterators on maps
>> was added. External data structures can use this interface to provide
>> direct key and val iterators via keys and vals.
>> 
>> These enhancements are particularly effective when used
>> in tandem with transducers via transduce, sequence, into, and
>> eduction.
>> 
>> * [CLJ-1603](http://dev.clojure.org/jira/browse/CLJ-1603)
>> * [CLJ-1515](http://dev.clojure.org/jira/browse/CLJ-1515)
>> * [CLJ-1602](http://dev.clojure.org/jira/browse/CLJ-1602)
>> * [CLJ-1669](http://dev.clojure.org/jira/browse/CLJ-1669)
>> 
>> ### 1.7 Printing as data (alpha6)
>> 
>> There have been enhancements in how the REPL prints values without a
>> print-method, specifically Throwable and the fallthrough Object case.
>> Both cases now print in a tagged literal data form that can be read
>> by the reader.
>> 
>> Unhandled objects print with the class, hash code, and toString:
>> 
>>      user=> *ns*
>>      #object[clojure.lang.Namespace 0x55aa628 "user"]
>> 
>> Thrown exceptions will still be printed in the normal way by the default
>> REPL but printing them to a stream will show a different form:
>> 
>>      user=> (/ 1 0)
>>      ArithmeticException Divide by zero  clojure.lang.Numbers.divide 
>> (Numbers.java:158)
>>      user=> (println *e)
>>      #error{:cause Divide by zero,
>>                 :via [{:type java.lang.ArithmeticException,
>>                            :message Divide by zero,
>>                                :at [clojure.lang.Numbers divide Numbers.java 
>> 158]}],
>>                 :trace
>>                   [[clojure.lang.Numbers divide Numbers.java 158]
>>                        [clojure.lang.Numbers divide Numbers.java 3808]
>>                        [user$eval5 invoke NO_SOURCE_FILE 3]
>>                        ;; elided ...
>>                        ]]}
>> 
>> ## 2 Enhancements
>> 
>> ### 2.1 Error messages
>> 
>> * [CLJ-1261](http://dev.clojure.org/jira/browse/CLJ-1261)
>>   Invalid defrecord results in exception attributed to consuming ns instead 
>> of defrecord ns
>> * [CLJ-1169](http://dev.clojure.org/jira/browse/CLJ-1169)
>>   Report line,column, and source in defmacro errors
>> * [CLJ-1297](http://dev.clojure.org/jira/browse/CLJ-1297)
>>   Give more specific hint if namespace with "-" not found to check file uses 
>> "_"
>> 
>> ### 2.2 Documentation strings
>> 
>> * [CLJ-1417](http://dev.clojure.org/jira/browse/CLJ-1417)
>>   clojure.java.io/input-stream has incorrect docstring
>> * [CLJ-1357](http://dev.clojure.org/jira/browse/CLJ-1357)
>>   Fix typo in gen-class doc-string
>> * [CLJ-1479](http://dev.clojure.org/jira/browse/CLJ-1479)
>>   Fix typo in filterv example
>> * [CLJ-1480](http://dev.clojure.org/jira/browse/CLJ-1480)
>>   Fix typo in defmulti docstring
>> * [CLJ-1477](
>> ...
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Clojure Dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure-dev+unsubscr...@googlegroups.com.
> To post to this group, send email to clojure-...@googlegroups.com.
> Visit this group at http://groups.google.com/group/clojure-dev.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to