.. include:: ../../global.rst .. _`struct type`: Structs ======= Structs are named indexed collections of references to values. Structs have two parts: a *type* which declares the *field* names and an optional *parent* type; and an *instance* of a struct type which has a reference to a value for each field. Defining Struct Types --------------------- Defining struct types is slightly roundabout because some struct types are defined in :lname:`C` so that the :lname:`C` code can create instances of the struct types. Furthermore, the :lname:`C` code does not need accessor functions as it can access the internals of the struct types directly. That said, the :lname:`Idio` code *does* need to have the accessor functions available otherwise it can't access the struct internals. From the :lname:`C` perspective, we have defined a struct type and we only need to have :lname:`Idio` define the predicate, an instance constructor and accessors. This is done with calls to :ref:`define-struct-accessors-only `. From the :lname:`Idio` perspective, we need to define a struct type and then carry on with what the :lname:`C` struct types do. So :ref:`define-struct ` takes the struct type name and creates the struct type and then calls :ref:`define-struct-accessors-only ` as is done for the :lname:`C` struct types. There are slight variations on the above with :ref:`export-struct ` and :ref:`export-struct-accessors-only ` which define then export the struct instance predicate, constructor and accessors. Struct Type Predicates ---------------------- .. _`struct-type?`: .. idio:function:: struct-type? o test if `o` is a struct type :param o: object to test :return: ``#t`` if `o` is a struct type, ``#f`` otherwise .. _`struct-type-isa?`: .. idio:function:: struct-type-isa? st type assert that struct type `st` isa a derivative of struct type `type` :param st: struct type to query :type st: struct type :param type: struct type to compare :type type: struct type :return: ``#t``/``#f`` Struct Type Constructors ------------------------ .. _`make-struct-type`: .. idio:function:: make-struct-type name parent fields create a struct type :param name: struct type name :type name: symbol :param parent: parent struct type :type parent: struct type or ``#n`` :param fields: field names :type fields: list of symbol :return: struct type :rtype: struct type Struct Type Attributes ---------------------- .. _`struct-type-name`: .. idio:function:: struct-type-name st return the name of struct type `st` :param st: struct type to query :type st: struct type :return: struct type name :rtype: symbol .. _`struct-type-parent`: .. idio:function:: struct-type-parent st return the parent of struct type `st` :param st: struct type to query :type st: struct type :return: struct type parent :rtype: struct type or ``#n`` .. _`struct-type-fields`: .. idio:function:: struct-type-fields st return the fields of struct type `st` :param st: struct type to query :type st: struct type :return: struct type fields :rtype: list of symbols or ``#n`` Struct Instance Predicates -------------------------- .. _`struct-instance?`: .. idio:function:: struct-instance? o test if `o` is a struct instance :param o: object to test :return: ``#t`` if `o` is a struct instance, ``#f`` otherwise .. _`struct-instance-isa?`: .. idio:function:: struct-instance-isa? si st assert that struct instance `si` isa a derivative of struct type `st` :param si: struct instance to query :type si: struct instance :param st: struct type to verify :type st: struct type :return: ``#t``/``#f`` Struct Instance Constructors ---------------------------- .. _`make-struct-instance`: .. idio:function:: make-struct-instance st values create an instance of struct type `st` assigning values to the struct type's fields :param st: struct type to create :type st: struct type :param values: values for fields :type type: list :return: struct instance Struct Instance Attributes -------------------------- .. _`struct-instance-type`: .. idio:function:: struct-instance-type si return the struct type of struct instance `si` :param si: struct instance to query :type si: struct instance :return: struct type :rtype: struct type .. _`struct-instance-fields`: .. idio:function:: struct-instance-fields si return the struct type fields of struct instance `si` :param si: struct instance to query :type si: struct instance :return: struct type fields :rtype: list .. _`struct-instance-ref`: .. idio:function:: struct-instance-ref si field return field `field` of struct instance `si` :param si: struct instance to query :type si: struct instance :param field: field name :type field: symbol :return: value .. _`struct-instance-set!`: .. idio:function:: struct-instance-set! si field v set field `field` of struct instance `si` to `v` :param si: struct instance to modify :type si: struct instance :param field: field name :type field: symbol :param v: value :type v: value :return: ``#`` .. _`%struct-instance-ref-direct`: .. idio:function:: %struct-instance-ref-direct si st index return integer field index `index` of struct instance `si` struct instance `si` is verified as being an instance of struct type `st` :param si: struct instance to query :type si: struct instance :param st: struct type to verify :type st: struct type :param index: field index :type index: fixnum :return: value .. _`%struct-instance-set-direct!`: .. idio:function:: %struct-instance-set-direct! si st index v set integer field index `index` of struct instance `si` struct instance `si` is verified as being an instance of struct type `st` :param si: struct instance to query :type si: struct instance :param st: struct type to verify :type st: struct type :param index: field index :type index: fixnum :param v: value :type v: value :return: ``#`` .. _`define-struct`: .. idio:template:: define-struct name [fields] define a structure type called `name` then call :ref:`define-struct-accessors-only ` with `name` and `fields` :param name: structure name :type name: symbol :param fields: list of field names, defaults to ``#n`` :type fields: list of symbols, optional .. note:: Using this form the structure type has no parent type. .. _`define-struct-accessors-only`: .. idio:template:: define-struct-accessors-only name [fields] define a structure instance constructor, predicate and accessors for structure fields :param name: structure name :type name: symbol :param fields: list of field names, defaults to ``#n`` :type fields: list of symbols, optional .. note:: Using this form: * the predicate will be :samp:`{name}?` * the constructor will be :samp:`make-{name}` * the accessors will be * :samp:`{name}-{field}` * :samp:`set-{name}-{field}!` .. _`export-struct`: .. idio:template:: export-struct name [fields] call :ref:`define-struct ` with `name` and `fields` and then export `name` and call :ref:`export-struct-accessors-of ` :param name: structure name :type name: symbol :param fields: list of field names, defaults to ``#n`` :type fields: list of symbols, optional .. _`export-struct-accessors-only`: .. idio:template:: export-struct-accessors-only name [fields] call :ref:`define-struct-accessors-only ` with `name` and `fields` and then export the constructor, predicate and field accessor names :param name: structure name :type name: symbol :param fields: list of field names, defaults to ``#n`` :type fields: list of symbols, optional .. include:: ../../commit.rst