<< Back to previous view

[CLJ-374] print/read syntax for defrecords Created: 05/Jun/10  Updated: 27/May/11  Resolved: 27/May/11

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.3
Fix Version/s: Release 1.3

Type: Enhancement Priority: Major
Reporter: Assembla Importer Assignee: Fogus
Resolution: Completed Votes: 1
Labels: None

Attachments: Text File CLJ-374-defrecord-literals.patch    
Patch: Code and Test
Approval: Ok
Waiting On: Stuart Halloway

 Comments   
Comment by Assembla Importer [ 24/Aug/10 9:32 AM ]

Converted from http://www.assembla.com/spaces/clojure/tickets/374

Comment by Assembla Importer [ 24/Aug/10 9:32 AM ]

stu said: If we are going to use #=, then how about modify record to take an optional metadata map before the keyvals:

(defn record
  "Construct an instance of record-type from keyvals.

   record-type is a keyword naming the record.
   keyvals can include *any* keyword/value pairs, and
   can be preceded by an optional metadata map."
  {:added "1.2"}
  [record-type & keyvals]
  {:pre [(keyword? record-type)]}
  (let [meta (when (map? (first keyvals)) (first keyvals))
        keyvals (if meta (rest keyvals) keyvals)]
    (record-implementation-detail-multimethod record-type meta (apply hash-map keyvals))))
</code></pre>

and then the read syntax can be

<pre><code>
#=(record :user.Foo {:some-meta 1} :a nil :c 3)
Comment by Assembla Importer [ 24/Aug/10 9:32 AM ]

richhickey said: I think you need to distinguish between print and print-dup contexts. I don't like the switch-on-type-of-first-arg in general. We don't do optional args preceding variadics. Also, normally we don't see metatadata in print unless print-meta is true.

I think a #= ctor call works for print-dup:

#=(Foo. 1 2 3 {:my :meta} {:other :field})

eliding the meta and extmap when neither is present:

#(Foo. 1 2 3)

not sure about ordinary print yet

Comment by Assembla Importer [ 24/Aug/10 9:32 AM ]

stu said: In the above, why isn't print-dup's effect recursive, e.g.

#=(user.Foo 1 2 3 #=(clojure.lang.PersistentArrayMap/create {:my :meta}) 
                                 #=(clojure.lang.PersistentArrayMap/create {:other :field}))

print-dup on maps certainly behaves that way, including nested maps.

Also, isn't a print-dup version that includes metadata only correct when print-meta is false?

Comment by Assembla Importer [ 24/Aug/10 9:32 AM ]

stu said: Updating tickets (#370, #366, #374)

Comment by Fogus [ 29/Apr/11 1:30 PM ]

Patch scoped to the discussion in this ticket and at http://dev.clojure.org/display/design/defrecord+improvements

Comment by Fogus [ 29/Apr/11 1:55 PM ]

Added IRecord patch file. Sorry.

Comment by Stuart Halloway [ 29/Apr/11 3:14 PM ]

Using primitive type hints seems to break the map->Record constructor:

(defrecord Bar [^long a b])
(map->Bar {:a 1 :b 2})
=> NullPointerException   clojure.lang.RT.longCast (RT.java:1008)
Comment by Stuart Halloway [ 29/Apr/11 3:21 PM ]

The patch does not address deftype. It gets (as a freebie) all the new stuff available to arbitrary Java classes, but no create method, positional fn, etc. I think we should do deftype as a separate patch.

Comment by Fogus [ 29/Apr/11 3:45 PM ]

RE: longCast

I will check that out. Thanks

RE: deftype

deftype does get a create and getBasis method, but the create is breaking because I am assuming a record ctor. I can fix that if we think that types should have a create that takes a map.

(deftype T [a])
(user.T/getBasis)
;=> [a]

(user.T/create {:a 1})
;; NoSuchMethodError

This is because I'm building a call to the record ctor that takes metadata and an extension map. Does it make sense to generate such a create that takes a map for types?

Thanks
:F

Comment by Fogus [ 05/May/11 5:25 PM ]

minor fixes from last patch set.

Comment by Rich Hickey [ 06/May/11 7:50 AM ]

deftypes shouldn't get any map-taking support as they are not mappy (mappish?). They should get positional support. defrecord and deftype stuff should go in together.

Comment by Fogus [ 10/May/11 7:20 AM ]

Latest patch includes changes to support deftype literals and removal of RecordExpr.

Comment by Christopher Redinger [ 25/May/11 2:25 PM ]

This patch has already been applied. Updating status of this ticket.

https://github.com/clojure/clojure/commit/ac1e8ad9f182dc2e8a5254f3e4b7b77c0258353d

Generated at Sun Sep 21 15:13:28 CDT 2014 using JIRA 4.4#649-r158309.