This site is a static rendering of the Trac instance that was used by R7RS-WG1 for its work on R7RS-small (PDF), which was ratified in 2013. For more information, see Home.

Source for ticket #45

cc


    

changetime

2012-11-29 01:54:10

component

WG1 - Core

description

(record-let <record-data>
            ((<variable> <field>)
              ...)
             <body>)

Where each <variable> is filled with the corresponding data <field> from <record-data> as in a <let> expression, then the <body> is evaluated with these bindinds added and last expressions is returned. It is an error if the <record-data> does not contain corresponding <fields>.

Notice that this works directly on the data itself and that the data may contain more fields than the one cited in the record-let expression allowing code to be reused for inherited records.

- Do we need to be able to check at runtime if a given record data has a given field ?

id

45

keywords


    

milestone


    

owner

alexshinn

priority

major

reporter

medernac

resolution

wontfix

severity


    

status

closed

summary

Record-let syntax and semantics

time

2010-03-11 16:16:58

type

enhancement

Changes

Change at time 2012-11-29 01:54:10

author

cowan

field

comment

newvalue


    

oldvalue

12

raw-time

1354125250322184

ticket

45

time

2012-11-29 01:54:10

Change at time 2012-11-29 01:54:10

author

cowan

field

resolution

newvalue

wontfix

oldvalue


    

raw-time

1354125250322184

ticket

45

time

2012-11-29 01:54:10

Change at time 2012-11-29 01:54:10

author

cowan

field

status

newvalue

closed

oldvalue

reopened

raw-time

1354125250322184

ticket

45

time

2012-11-29 01:54:10

Change at time 2012-11-29 01:54:00

author

cowan

field

comment

newvalue


    

oldvalue

11

raw-time

1354125240016932

ticket

45

time

2012-11-29 01:54:00

Change at time 2012-11-29 01:54:00

author

cowan

field

resolution

newvalue


    

oldvalue

fixed

raw-time

1354125240016932

ticket

45

time

2012-11-29 01:54:00

Change at time 2012-11-29 01:54:00

author

cowan

field

status

newvalue

reopened

oldvalue

closed

raw-time

1354125240016932

ticket

45

time

2012-11-29 01:54:00

Change at time 2011-07-10 18:28:44

author

alexshinn

field

comment

newvalue

We voted no.

oldvalue

10

raw-time

1310297324000000

ticket

45

time

2011-07-10 18:28:44

Change at time 2011-07-10 18:28:44

author

alexshinn

field

resolution

newvalue

fixed

oldvalue


    

raw-time

1310297324000000

ticket

45

time

2011-07-10 18:28:44

Change at time 2011-07-10 18:28:44

author

alexshinn

field

status

newvalue

closed

oldvalue

new

raw-time

1310297324000000

ticket

45

time

2011-07-10 18:28:44

Change at time 2010-03-17 02:22:38

author

medernac

field

comment

newvalue

Replying to [comment:8 kumoyuki]:

To illustrate the idea, here is what I am personnaly using in association with let-record for record definition with types:
  

{{{
(record-constructor <Constructor name>
		    <Type checker name>
		    <Fields name>
		    (<Type> <data> <getter>) ...)
}}}


Where I view type mainly as predicates. I don't have setters, but I
see no problem in adding it. Here are some examples:


{{{
;; A flat record
(record-constructor make-job
		    job-type?
		    job-fields
		    (real?   release  job-release)
		    (real?   duration  job-duration)
		    (string? username  job-username))

(define (List-of type?)
  (lambda (data)
    (and (list? data)
         (let loop ((tmp data))
	    (or (null? tmp)
	        (and (type? (car tmp))
	             (loop (cdr tmp))))))))

;; A record with recursive type field
(record-constructor Tree-of-integer
		    Tree-of-integer-type?
		    Tree-of-integer-fields
		    (integer? element Tree-of-integer->element)
		    ((List-of Tree-of-integer-type?) subtrees Tree-of-integer->subtrees))

(Tree-of-integer 17 (list (Tree-of-integer 12 '())))
}}}
		    

But I could also do type parameterization like this:


{{{
(record-constructor (<Constructor name> <Type parameter> ...)
		    <Type checker name>
		    <Fields name>
		    (<Type> <data> <getter>) ...)
}}}

For instance:		    
		    

{{{
(record-constructor (Tree type?)
		    Tree-type?
		    Tree-fields
		    (type? element Tree->get-element)
		    ((List-of (Tree type?)) subtrees Tree->get-subtrees))

}}}

And then generate records like this:		    
		    

{{{
(define make-integer-tree (Tree integer?))
(make-integer-tree 17 (list (make-integer-tree 12 '())))

(define make-string-tree (Tree string?))
(make-string-tree "foo" (list (make-string-tree "bar" '())))
}}}

Then let-record easily allows access to fields and I could reuse the same code for records sharing some fields.

oldvalue

8.9

raw-time

1268767358000000

ticket

45

time

2010-03-17 02:22:38

Change at time 2010-03-16 04:40:00

author

kumoyuki

field

comment

newvalue

Replying to [comment:7 cowan]:
> The only "methods" we have are getters, setters, and predicates.  It's not clear to me what the difference is between delegation and inheritance in that context.

The reference to inheritance was the OP's. The difference could be trivial; the issue is what types does a new value become a member of (and expose the interfaces of). I do realize that the proposal we are commenting on contains no such information, and I wonder how OP got to inheritance in the first place. The lack of anything resembling a type algebra, even as simple a one as SI, has often been mentioned as one of SRFI-9's main drawbacks, so I expect that it *will* come up somewhere along the line. In fact it is one of the few areas where I'd be willing to see more complexity come into Thing1.

oldvalue

7.8

raw-time

1268689200000000

ticket

45

time

2010-03-16 04:40:00

Change at time 2010-03-15 23:28:49

author

cowan

field

comment

newvalue

The only "methods" we have are getters, setters, and predicates.  It's not clear to me what the difference is between delegation and inheritance in that context.

oldvalue

6.7

raw-time

1268670529000000

ticket

45

time

2010-03-15 23:28:49

Change at time 2010-03-15 14:58:39

author

kumoyuki

field

comment

newvalue

Replying to [comment:4 medernac]:
> By the way notice that if we have only single-inheritance (hierachy of types) 
> it is easy by convention to always use the same index number as parent-type
> fields. So an interpreter/compiler just has to lookup from the fields name
> which is the corresponding index for fields.

It's worth noting that delegation techniques are strictly more expressive than inheritance based ones and they completely avoid the hair of multiple inheritance (this was shown in an OOPSLA paper somewhere around 1994-1996 but I've forgotten the title). I think it would be lovely to see a programmer-defined aggregate system that supported delegation as the core mechanism rather than any form of inheritance.

oldvalue

4.6

raw-time

1268639919000000

ticket

45

time

2010-03-15 14:58:39

Change at time 2010-03-15 07:24:27

author

arcfide

field

comment

newvalue

Replying to [comment:4 medernac]:
> By the way notice that if we have only single-inheritance (hierachy of types) it is easy by convention to always use the same index number as parent-type fields. So an interpreter/compiler just has to lookup from the fields name which is the corresponding index for fields.

If we have to do lookups, I'm a little concerned. Lookups can be elided when dealing with a sufficiently smart compiler in many/most cases, but not all, and with interpreters that don't do such optimizations, you will end up having much slower access. Especially when dealing with parents that could come from other libraries, the speed issues become more obvious since it is very hard to do that sort of reasoning in general.

oldvalue

4.5

raw-time

1268612667000000

ticket

45

time

2010-03-15 07:24:27

Change at time 2010-03-13 18:30:02

author

medernac

field

comment

newvalue

Replying to [comment:2 arcfide]:
> An alternate implementation that uses (<record-data> <record-type-descriptor>) instead of <record-data> above will enable record-let to work entirely at compile-time. 

I am a bit reluctant to this but I agree that could be done that way.

> 
> I also think that let-record is maybe a more consistent name.

I am Ok for whatever name.

By the way notice that if we have only single-inheritance (hierachy of types) it is easy by convention to always use the same index number as parent-type fields. So an interpreter/compiler just has to lookup from the fields name which is the corresponding index for fields.

oldvalue

2.4

raw-time

1268476202000000

ticket

45

time

2010-03-13 18:30:02

Change at time 2010-03-13 18:23:30

author

medernac

field

comment

newvalue

Replying to [comment:1 cowan]:
> This will only work if the field names are available at run time, unless the type is also available at compile time.

Yes, It must keep track of fields name. Some kind of reflection is needed for that to work. 

By the way, would it be better if fields are restricted to be symbols only ? 

oldvalue

1.3

raw-time

1268475810000000

ticket

45

time

2010-03-13 18:23:30

Change at time 2010-03-12 12:27:43

author

arcfide

field

comment

newvalue

An alternate implementation that uses (<record-data> <record-type-descriptor>) instead of <record-data> above will enable record-let to work entirely at compile-time. 

I also think that let-record is maybe a more consistent name.

oldvalue

2

raw-time

1268368063000000

ticket

45

time

2010-03-12 12:27:43

Change at time 2010-03-12 12:22:34

author

cowan

field

comment

newvalue

This will only work if the field names are available at run time, unless the type is also available at compile time.

oldvalue

1

raw-time

1268367754000000

ticket

45

time

2010-03-12 12:22:34