Clojure struct constructor needs keywords badly. Right now it's position-dependent and only way to know what each sub-expression is doing is to look up the definition of the structure.
(struct person 6.3 63 63)
What do the magic numbers mean? Dunno, you need to look up defstruct definition. In Common Lisp, it's:
"Clojure doesn’t have the parse-integer function, but I was quickly able to implement something that did the job by calling out to the Java parseInt method."
This has to be remedied. You need to have native control over basic reading/writing; don't offshore that to another language, even one your language is implemented on-top of.
I agree with the sentiment against ASH (Arithmetic-SHift); seriously, division/multiplication as 2^N shifts is a performance hack, and a useless one at that (smart compilers already do this, and stupid ones are bytecode compilers.)
Common Lisp already has about 9 division operators (yes, NINE) and it would have been a good opportunity to introduce them and their various uses. They are: /, floor, ffloor, ceiling, fceiling, truncate, ftruncate, round, fround -- for integers and floats respectively[1], along with MOD and REM
[1] excellent candidates for removal in future CL with CLOS-based type hierarchy; type-dispatch ftw! With ML-style type annotations it would even be feasible to do type hints inline, like (values (/@double-float 22 7) (/@int 22 7)) using @ because colon is a package separator.
First of all, Clojure has struct-map, which supports keywords, much like default Common Lisp struct constructors.
Second, Clojure's defstruct is on its way out. defrecord provides similar functionality with far better performance. By default, however, it does have the positional-arguments-only flaw. My personal favorite workaround is a small macro from this post: http://groups.google.com/group/clojure/msg/5206fac13144ea99
No comment about numerical operations in Clojure: it's a sensitive topic. :)
Here: http://clojure.org/data_structures, see the entry for StructMaps. The page on datatypes* also implies heavily that structs have been phased out in favor of records, as no reason to use structs over records is presented.
Christophe Grand pointed out in the comments that a plain map should be used instead of a struct, so your example in Clojure would be:
{:height 6.3 :age 63 :weight-in-kg 63}
That works in the short term, but beyond that, Clojure will need to resolve that issue.
Records are not the same thing as hash-tables. A record, or struct, is a single unit value, while a hash-table, or map, is an aggregate container. There is an implicit contract in place; a record is guaranteed to have JUST the fields it's defined to have, while a map can grow at run time (are you going to test for the fields you want and ignore the rest? quack quack! you can't add fields to a record at runtime, so the two are NOT interchangeable. Equality is a transitive relation, while duck-typing is not.)
A record is a generalization of the concept of "value" beyond data types immediately representable by machine. While a hash-table is a generalization of arrays, an aggregate of values, addressable by an index (hash-tables remedy the silly assumption that an index must be of an integral value.)
To give an analogy; it's like asking what's the best way to group a bunch of papers (folder, envlope, binder) and then hearing someone suggest "bookshelf!".
Again, OK short-term, but stinks. Fix the structs; even C has dot and arrow notations, making the field names clear.
Almost. Record types are checked as part of Clojure's "=", but not as part of Java's ".equals". See [1] and linked material. This means that Foo{:x 1} and Bar{:x 1} will collide in sets and as map keys (of Clojure or Java varieties). This seems a bit icky to me, but seems to be intentional.
Records also provide better performance than hash tables for their defined keys.
You can think of them as a Java class that has certain fields (it's named fields) and also implements the Map interface for additional expandability. Records provide "accessor" methods for their named fields that provide bare-metal JVM performance.
"Clojure doesn’t have the parse-integer function, but I was quickly able to implement something that did the job by calling out to the Java parseInt method."
This has to be remedied. You need to have native control over basic reading/writing; don't offshore that to another language, even one your language is implemented on-top of.
I agree with the sentiment against ASH (Arithmetic-SHift); seriously, division/multiplication as 2^N shifts is a performance hack, and a useless one at that (smart compilers already do this, and stupid ones are bytecode compilers.)
Common Lisp already has about 9 division operators (yes, NINE) and it would have been a good opportunity to introduce them and their various uses. They are: /, floor, ffloor, ceiling, fceiling, truncate, ftruncate, round, fround -- for integers and floats respectively[1], along with MOD and REM
[1] excellent candidates for removal in future CL with CLOS-based type hierarchy; type-dispatch ftw! With ML-style type annotations it would even be feasible to do type hints inline, like (values (/@double-float 22 7) (/@int 22 7)) using @ because colon is a package separator.