5 ms·
Common Lisp, Clojure and Evolution
- mahmud 16y agoClojure 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: (make-person :height 6.3 :age 63 :weight-in-kg 63) ;; or better :weight (kg 63) Then "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.
- jb3 16y agoChristophe 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}
- deleted 16y ago[deleted]
- mahmud 16y agoThat 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.
- jkkramer 16y agoRecords and structs can grow at runtime (insofar as immutable data structures grow). user> (defrecord Foo [x]) user.Foo user> (assoc (Foo. 1) :y 2) #:user.Foo{:x 1, :y 2} user> (defstruct foo :x) #'user/foo user> (assoc (struct-map foo :x 1) :y 2) {:x 1, :y 2}
- mahmud 16y agoWell, what do you know, Clojure records and hash-tables are equal (strongly.) I will announce this great news to a few of my closest friends :-)
- jkkramer 16y agoAlmost. Record types are checked as part of full equality. So record Foo{:x 1} is not equal to Bar{:x 1} or to {:x 1}.
- 16y ago
- gcv 16y agoFirst 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 http://groups.google.com/group/clojure/msg/5206fac13144ea99 No comment about numerical operations in Clojure: it's a sensitive topic. :)
- mahmud 16y agoEven the manual recommends records in lieu of struct-map. And yes, that flaw is icky; one of the few in Hickey's otherwise excellent track-record in good taste.
- amouat 16y agoThe manual? What's the manual?
- whateverer 16y agoHere: http://clojure.org/data_structures 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. * http://clojure.org/datatypes http://clojure.org/datatypes
- lukev 16y agoThe defrecord constructor-by-map feature is actively being worked on for version 1.3.