functional structures in scheme
/lib/struct.scm contains a function to generate functional "structs." these structs are immutable and are implemented as lambdas. you can create a new "struct type" by calling the
(struct) function. consider the following code:
(define user (struct 'name 'pw 'rank 'email 'age 'attunements)) (define juan (user "juán peralta" "p@labra-secr3ta" "special agent" "firstname.lastname@example.org" 69 '("hushed whispers" "the unconquered wilderness" "careful duplicity")))
this code first creates a struct type, characterized by the function
(user) is called on the correct number of arguments, it generates a new record of that type. the new record is itself a function. to access a record, you simply call the function with the name of the field to look up. the library also supports what's known as "functional record update syntax," a pattern in which a new struct is returned with different values for named fields. this library currently only supports updating one record at a time, but you can get around this through currying.
(juan) ; → '("juán peralta" "p@labra-secr3ta" "special agent" "email@example.com" 69 '("hushed whispers" "the unconquered wilderness" "careful duplicity"))
(juan 'email) ; → "firstname.lastname@example.org" (juan 'attunements) ; → '("hushed whispers" "the unconquered wilderness" "careful duplicity")
(define juan-with-new-pw (juan 'pw "pendej0-supremo")) (juan-with-new-pw 'name) ; → "juán peralta" (juan-with-new-pw 'pw) ; → "pendej0-supremo"
(define clarabetta ((juan 'name "clarabetta kincaid") 'email "email@example.com))
(clarabetta 'email) ; → "firstname.lastname@example.org"
structs, as you can see above, can also be called without arguments to return a list of all the data they contain. the code is fairly straightforward, implemented completely without macros, and shouldn't be difficult to understand for anyone familiar with functional programming. it's also in my experience tremendously useful, simplifying a number of tasks that would otherwise be unnecessarily complicated in Scheme compared to C, and has the advantage of field names being expressions - you could just as easily call a function to return the appropriate field name as write one in yourself.