{Begin SubSec File Package Types} {Title File Package Types} {Text {Tag FilePkgTypes} {index *PRIMARY* File package types} In addition to the definitions of functions and values of variables, source files in Interlisp can contain a variety of other information, e.g. property lists, record declarations, macro definitions, hash arrays, etc. In order to treat such a diverse assortment of data uniformly from the standpoint of file operations, the file package uses the concept of a {it typed definition}, of which a function definition is just one example. A typed definition associates with a name (usually a litatom), a definition of a given type (called the file package type). Note that the same name may have several definitions of different types. For example, a litatom may have both a function definition and a variable definition. The file package also keeps track of the file that a particular typed definition is stored on, so one can think of a typed definition as a relation between four elements: a name, a definition, a type, and a file. A file package type is an abstract notion of a class of objects which share the property that every object of the same file package type is stored, retrieved, edited, copied etc., by the file package in the same way. Each file package type is identified by a litatom, which can be given as an argument to the functions that manipulate typed definitions. The user may define new file package types, as described in {PageRef Fn FILEPKGTYPE}. {VarDef {Name FILEPKGTYPES} {Text The value of {var FILEPKGTYPES} is a list of all file package types, including any that may have been defined by the user. }} The file package is initialized with the following built-in file package types: {Def {Type (File Package Type)} {Name ADVICE} {Text Used to access "advice" modifying a function (see {PageRef Term Advising functions}). }} {Def {Type (File Package Type)} {Name ALISTS} {Text Used to access objects stored on an association list that is the value of a litatom (see {PageRef Term Association lists}). A variable is declared to have an association list as its value by putting on its property list the property {index *PRIMARY* VARTYPE Prop}{prop VARTYPE} with value {lisp ALIST}. In this case, each dotted pair on the list is an object of type {lisp ALISTS}. When the value of such a variable is changed, only those entries in the association list that are actually changed or added are marked as changed objects of type {lisp ALISTS} (with "name" {lisp ({arg LITATOM} {arg KEY})}). Objects of type {lisp ALISTS} are dumped via the {filecom ALISTS} or {filecom ADDVARS} file package commands. Note that some association lists are used to "implement" other file package types. For example, the value of the global variable {var USERMACROS} implements the file package type {lisp USERMACROS} and the values of {var LISPXMACROS} and {var LISPXHISTORYMACROS} implement the file package type {lisp LISPXMACROS}. This is indicated by putting on the property list of the variable the property {prop VARTYPE} with value a list of the form {lisp (ALIST {arg FILEPKGTYPE})}. For example, {lisp (GETPROP 'LISPXHISTORYMACROS 'VARTYPE) => (ALIST LISPXMACROS)}. }} {Def {Type (File Package Type)} {Name COURIERPROGRAMS} {Text Used to access Courier programs (see {PageRef Term Courier programs}). }} {Def {Type (File Package Type)} {Name EXPRESSIONS} {Text Used to access lisp expressions that are put on a file by using the {pacom REMEMBER} programmers assistant command ({PageRef PACom REMEMBER}), or by explicitly putting the {filecom P} file package command ({PageRef FileCom P}) on the filecoms. }} {Def {Type (File Package Type)} {Name FIELDS} {Text Used to access fields of records. The "definition" of an object of type {lisp FIELDS} is a list of all the record declarations which contain the name. See {PageRef Term Record Package}. }} {Def {Type (File Package Type)} {Name FILEPKGCOMS} {Text Used to access file package commands and types. A single name can be defined both as a file package type and a file package command. The "definition" of an object of type {lisp FILEPKGCOMS} is a list structure of the form {lisp ((COM . {arg COMPROPS}) (TYPE . {arg TYPEPROPS}))}, where {arg COMPROPS} is a property list specifying how the name is defined as a file package command by {fn FILEPKGCOM} ({PageRef Fn FILEPKGCOM}), and {arg TYPEPROPS} is a property list specifying how the name is defined as a file package type by {fn FILEPKGTYPE} ({PageRef Fn FILEPKGTYPE}). }} {Def {Type (File Package Type)} {Name FILES} {Text Used to access files. This file package type is most useful for renaming files. The "definition" of a file is not a useful structure. {Begin Note} Date: 16 Oct 1978 1:42 pm (Monday) From: Masinter (implementation change) GETDEF(X FILES) now returns a more complicated data structure than before (it used to just return the COMS for the file, now the value of GETDEF includes part of the FILE and FILEDATES property of X). PUTDEF(X FILE DEFINITION) will MAKEFILE(X) copying functions if necessary from the "old" file (supplied as part of the DEFINITION). This change should not affect any users (the only use I have ever made of FILES as a type is to rename them); it made it possible to remove a special check in the COPYDEF function to handle this case. {End Note} }} {Def {Type (File Package Type)} {Name FILEVARS} {Text Used to access Filevars (see {PageRef Term FileVars}). }} {Def {Type (File Package Type)} {Name FNS} {Text Used to access function definitions. }} {Def {Type (File Package Type)} {Name I.S.OPRS} {Text Used to access the definitions of iterative statement operators (see {PageRef Term Iterative statements}). }} {Def {Type (File Package Type)} {Name LISPXMACROS} {Text Used to access programmer's assistant commands defined on the variables {lisp LISPXMACROS} and {var LISPXHISTORYMACROS} (see {PageRef Var LISPXMACROS}). }} {Def {Type (File Package Type)} {Name MACROS} {Text Used to access macro definitions (see {PageRef Term Macros}). }} {Def {Type (File Package Type)} {Name PROPS} {Text Used to access objects stored on the property list of a litatom (see {PageRef Term Properties of litatoms}). When a property is changed or added, an object of type {lisp PROPS}, with "name" {lisp ({arg LITATOM} {arg PROPNAME})} is marked as being changed. Note that some litatom properties are used to implement other file package types. For example, the property {prop MACRO} implements the file package type {lisp MACROS}, the property {prop ADVICE} implements {lisp ADVICE}, etc. This is indicated by putting the property {prop PROPTYPE},{index *PRIMARY* PROPTYPE Prop} with value of the file package type on the property list of the property name. For example, {lisp (GETPROP 'MACRO 'PROPTYPE) => MACROS}. When such a property is changed or added, an object of the corresponding file package type is marked. If {lisp (GETPROP {arg PROPNAME} 'PROPTYPE) => IGNORE}, the change is ignored. The {prop FILE}, {prop FILEMAP}, {prop FILEDATES}, etc. properties are all handled this way. (Note that {lisp IGNORE} cannot be the name of a file package type implemented as a property). }} {Def {Type (File Package Type)} {Name RECORDS} {Text Used to access record declarations (see {PageRef Term Record Package}). }} {Def {Type (File Package Type)} {Name RESOURCES} {Text Used to access resources (see {PageRef Term Resources}). }} {Def {Type (File Package Type)} {Name TEMPLATES} {Text Used to access Masterscope templates (see {PageRef Term Masterscope Templates}). }} {Def {Type (File Package Type)} {Name USERMACROS} {Text Used to access user edit macros (see {PageRef Term Edit Macros}). }} {Def {Type (File Package Type)} {Name VARS} {Text Used to access top-level variable values. }} {Begin Note} doc synonyms??? synonyms for file package types: (LISPXCOMS . LISPXMACROS) (FILEPKGTYPES . FILEPKGCOMS) (EDITMACROS . USERMACROS) {End Note} {Begin SubSec Functions for Manipulating Typed Definitions} {Title Functions for Manipulating Typed Definitions} {Text The functions described below can be used to manipulate typed definitions, without needing to know how the manipulations are done. For example, {lisp (GETDEF 'FOO 'FNS)} will return the function definition of {lisp FOO}, {lisp (GETDEF 'FOO 'VARS)} will return the variable value of {lisp FOO}, etc. All of the functions use the following conventions: (1) All functions which make destructive changes are undoable. (2) Any argument that expects a list of litatoms will also accept a single litatom, operating as though it were enclosed in a list. For example, if the argument {arg FILES} should be a list of files, it may also be a single file. (3) {arg TYPE} is a file package type. {arg TYPE}={lisp NIL} is equivalent to {arg TYPE}={lisp FNS}. The singular form of a file package type is also recognized, e.g. {arg TYPE}={lisp VAR} is equivalent to {arg TYPE}={lisp VARS}. (4) {arg FILES}={lisp NIL} is equivalent to {arg FILES}={var FILELST}. (5) {arg SOURCE} is used to indicate the source of a definition, that is, where the definition should be found. {arg SOURCE} can be one of: {Begin LabeledList SOURCE} {Name {lisp CURRENT}} {Text Get the definition currently in effect. } {Name {lisp SAVED}} {Text Get the "saved" definition, as stored by {fn SAVEDEF} ({PageRef Fn SAVEDEF}). } {Name {lisp FILE}} {Text Get the definition contained on the (first) file determined by {fn WHEREIS} ({PageRef Fn WHEREIS}). Note: {fn WHEREIS} is called with {arg FILES}={lisp T}, so that if the WHEREIS library package is loaded, the WHEREIS data base will be used to find the file containing the definition. } {Name {lisp ?}} {Text Get the definition currently in effect if there is one, else the saved definition if there is one, otherwise the definition from a file determined by {fn WHEREIS}. Like specifying {lisp CURRENT}, {lisp SAVED}, and {lisp FILE} in order, and taking the first definition that is found. } {Name a file name} {Name a list of file names} {Text Get the definition from the first of the indicated files that contains one. } {Name {lisp NIL}} {Text In most cases, giving {arg SOURCE}={lisp NIL} (or not specifying it at all) is the same as giving {lisp ?}, to get either the current, saved, or filed definition. However, with {fn HASDEF}, {arg SOURCE}={lisp NIL} is interpreted as equal to {arg SOURCE}={lisp CURRENT}, which only tests if there is a current definition. } {End LabeledList SOURCE} {note HASDEF, GETDEF now only accept file package types (not commands), e.g. GETDEF(FOO COMS) causes error "COMS not file package type". } The operation of most of the functions described below can be changed or extended by modifying the appropriate properties for the corresponding file package type using the function {fn FILEPKGTYPE}, described on {PageRef Fn FILEPKGTYPE}. {FnDef {FnName GETDEF} {FnArgs NAME TYPE SOURCE OPTIONS} {Text Returns the definition of {arg NAME}, of type {arg TYPE}, from {arg SOURCE}. For most types, {fn GETDEF} returns the expression which would be pretty printed when dumping {arg NAME} as {arg TYPE}. For example, for {arg TYPE}={lisp FNS}, an {lisp EXPR} definition is returned, for {arg TYPE}={lisp VARS}, the value of {arg NAME} is returned, etc. {arg OPTIONS} is a list which specifies certain options: {Begin LabeledList GETDEF options} {Name {lisp NOERROR}} {Text {fn GETDEF} causes an error if an appropriate definition cannot be found, unless {arg OPTIONS} is or contains {lisp NOERROR}. In this case, {fn GETDEF} returns the value of the {lisp NULLDEF} file package type property ({PageRef (File Package Type Property) NULLDEF}), usually {lisp NIL}. } {Name a string} {Text If {arg OPTIONS} is or contains a string, that string will be returned if no definition is found (and {lisp NOERROR} is not among the options). The caller can thus determine whether a definition was found, even for types for which {lisp NIL} or {lisp NOBIND} are acceptable definitions. } {Name {lisp NOCOPY}} {Text {fn GETDEF} returns a copy of the definition unless {arg OPTIONS} is or contains {lisp NOCOPY}. } {Name {lisp EDIT}} {Text If {arg OPTIONS} is or contains {lisp EDIT}, {fn GETDEF} returns a copy of the definition unless it is possible to edit the definition "in place." With some file package types, such as functions, it is meaningful (and efficient) to edit the definition by destructively modifying the list structure, without calling {fn PUTDEF}. However, some file package types (like records) need to be "installed" with {fn PUTDEF} after they are edited. The default {lisp EDITDEF} (see {PageRef (File Package Type Property) EDITDEF}) calls {fn GETDEF} with {arg OPTIONS} of {lisp (EDIT NOCOPY)}, so it doesn't use a copy unless it has to, and only calls {fn PUTDEF} if the result of editing is not {fn EQUAL} to the old definition. } {Name {lisp NODWIM}} {Text A {lisp FNS} definition will be dwimified if it is likely to contain CLISP unless {arg OPTIONS} is or contains {lisp NODWIM}. } {End LabeledList GETDEF options} {note additional GETDEF options which need to be explained: SPELL, HASDEF, FAST, ARGLIST} }} {FnDef {FnName PUTDEF} {FnArgs NAME TYPE DEFINITION REASON} {Text Defines {arg NAME} of type {arg TYPE} with {arg DEFINITION}. For {arg TYPE}={lisp FNS}, does a {fn DEFINE}; for {arg TYPE}={lisp VARS}, does a {fn SAVESET}, etc. For {arg TYPE}={lisp FILES}, {fn PUTDEF} establishes the command list, notices {arg NAME}, and then calls {fn MAKEFILE} to actually dump the file {arg NAME}, copying functions if necessary from the "old" file (supplied as part of {arg DEFINITION}). {fn PUTDEF} calls {fn MARKASCHANGED} ({PageRef Fn MARKASCHANGED}) to mark {arg NAME} as changed, giving a reason of {arg REASON}. If {arg REASON} is {lisp NIL}, the default is {lisp DEFINED}. Note: If {arg TYPE}={lisp FNS}, {fn PUTDEF} prints a warning if the user tries to redefine a function on the list {index UNSAFE.TO.MODIFY.FNS Var}{var UNSAFE.TO.MODIFY.FNS} ({PageRef Var UNSAFE.TO.MODIFY.FNS}). }} {FnDef {FnName HASDEF} {FnArgs NAME TYPE SOURCE SPELLFLG} {Text Returns {lisp (OR {arg NAME} T)} if {arg NAME} is the name of something of type {arg TYPE}. If not, attempts spelling correction if {arg SPELLFLG}={lisp T}, and returns the spelling-corrected {arg NAME}. Otherwise returns {lisp NIL}. {lisp (HASDEF NIL {arg TYPE})} returns {lisp T} if {lisp NIL} has a valid definition. Note: if {arg SOURCE}={lisp NIL}, {arg HASDEF} interprets this as equal to {arg SOURCE}={lisp CURRENT}, which only tests if there is a current definition. }} {FnDef {FnName TYPESOF} {FnArgs NAME POSSIBLETYPES IMPOSSIBLETYPES SOURCE} {Text Returns a list of the types in {arg POSSIBLETYPES} but not in {arg IMPOSSIBLETYPES} for which {arg NAME} has a definition. {lisp FILEPKGTYPES} is used if {arg POSSIBLETYPES} is {lisp NIL}. }} {FnDef {FnName COPYDEF} {FnArgs OLD NEW TYPE SOURCE OPTIONS} {Text Defines {arg NEW} to have a copy of the definition of {arg OLD} by doing {fn PUTDEF} on a copy of the definition retrieved by {lisp (GETDEF {arg OLD} {arg TYPE} {arg SOURCE} {arg OPTIONS})}. {arg NEW} is substituted for {arg OLD} in the copied definition, in a manner that may depend on the {arg TYPE}. {note I assume that COPYDEF will fail miserably if given any user-defined file package type which contains internal references to its name. Perhaps there should be a COPYDEF attribute definable by FILEPKGTYPE ???} For example, {lisp (COPYDEF 'PDQ 'RST 'FILES)} sets up {lisp RSTCOMS} to be a copy of {lisp PDQCOMS}, changes things like {lisp (VARS * PDQVARS)} to be {lisp (VARS * RSTVARS)} in {lisp RSTCOMS}, and performs a {fn MAKEFILE} on {lisp RST} such that the appropriate definitions get copied from {lisp PDQ}. {fn COPYDEF} disables the {lisp NOCOPY} option of {fn GETDEF}, so {arg NEW} will always have a {it copy} of the definition of {arg OLD}. Note: {fn COPYDEF} substitutes {arg NEW} for {arg OLD} throughout the definition of {arg OLD}. This is usually the right thing to do, but in some cases, e.g., where the old name appears within a quoted expression but was not used in the same context, the user must re-edit the definition. }} {FnDef {FnName DELDEF} {FnArgs NAME TYPE} {Text Removes the definition of {arg NAME} as a {arg TYPE} that is currently in effect. }} {FnDef {FnName SHOWDEF} {FnArgs NAME TYPE FILE} {Text Prettyprints the definition of {arg NAME} as a {arg TYPE} to {arg FILE}. This shows the user how {arg NAME} would be written to a file. Used by {fn ADDTOFILES?} ({PageRef Fn ADDTOFILES?}). }} {FnDef {FnName EDITDEF} {FnArgs NAME TYPE SOURCE EDITCOMS} {Text Edits the definition of {arg NAME} as a {arg TYPE}. Essentially performs {lispcode (PUTDEF {arg NAME} {arg TYPE} (EDITE (GETDEF {arg NAME} {arg TYPE} {arg SOURCE}) {arg EDITCOMS}))} }} {FnDef {FnName SAVEDEF} {FnArgs NAME TYPE DEFINITION} {Text Sets the "saved" definition of {arg NAME} as a {arg TYPE} to {arg DEFINITION}. If {arg DEFINITION}={lisp NIL}, the current definition of {arg NAME} is saved. If {arg TYPE}={lisp FNS} (or {lisp NIL}), the function definition is saved on {arg NAME}'s property list under the property {index EXPR Prop}{prop EXPR}, or {index *PRIMARY* CODE Prop}{prop CODE} (depending on the {index FNTYP FN}{fn FNTYP} of the function definition). If {lisp (GETD {arg NAME})} is non-{lisp NIL}, but {lisp (FNTYP {arg FN})}={lisp NIL}, {fn SAVEDEF} saves the definition on the property name {index *PRIMARY* LIST Prop}{lisp LIST}. This can happen if a function was somehow defined with an illegal expr definition, such as {lisp (LAMMMMDA (X) {ellipsis})}. If {arg TYPE}={lisp VARS}, the definition is stored as the value of the {index *PRIMARY* VALUE Prop}{prop VALUE} property of {arg NAME}. For other types, the definition is stored in an internal data structure, from where it can be retrieved by {fn GETDEF} or {fn UNSAVEDEF}. }} {FnDef {FnName UNSAVEDEF} {FnArgs NAME TYPE {anonarg}} {Text Restores the "saved" definition of {arg NAME} as a {arg TYPE}, making it be the current definition. Returns {arg PROP}. If {arg TYPE}={lisp FNS} (or {lisp NIL}), {fn UNSAVEDEF} unsaves the function definition from the {prop EXPR} property if any, else {prop CODE}, and returns the property name used. {fn UNSAVEDEF} also recognizes {arg TYPE}={lisp EXPR}, {lisp CODE}, or {lisp LIST}, meaning to unsave the definition only from the corresponding property only. If {index DFNFLG Var}{var DFNFLG} is not {lisp T} (see {PageRef Var DFNFLG}), the current definition of {arg NAME}, if any, is saved using {fn SAVEDEF}. Thus one can use {fn UNSAVEDEF} to switch back and forth between two definitions. }} {FnDef {FnName LOADDEF} {FnArgs NAME TYPE SOURCE} {Text Equivalent to {lisp (PUTDEF {arg NAME} {arg TYPE} (GETDEF {arg NAME} {arg TYPE} {arg SOURCE}))}. {fn LOADDEF} is essentially a generalization of {fn LOADFNS}, e.g. it enables loading a single record declaration from a file. Note that {lisp (LOADDEF {arg FN})} will give {arg FN} an {lisp EXPR} definition, either obtained from its property list or a file, unless it already has one. {note calls GETDEF with OPTIONS=(NODWIM NOCOPY)} }} {FnDef {FnName CHANGECALLERS} {FnArgs OLD NEW TYPES FILES METHOD} {Text Finds all of the places where {arg OLD} is used as any of the types in {arg TYPES} and changes those places to use {arg NEW}. For example, {lisp (CHANGECALLERS 'NLSETQ 'ERSETQ)} will change all calls to {fn NLSETQ} to be calls to {fn ERSETQ}. Also changes occurrences of {arg OLD} to {arg NEW} inside the filecoms of any file, inside record declarations, properties, etc. {fn CHANGECALLERS} attempts to determine if {arg OLD} might be used as more than one type; for example, if it is both a function and a record field. If so, rather than performing the transformation {lisp {arg OLD} -> {arg NEW}} automatically, the user is allowed to edit all of the places where {arg OLD} occurs. For each occurrence of {arg OLD}, the user is asked whether he wants to make the replacement. If he responds with anything except {lisp Yes} or {lisp No}, the editor is invoked on the expression containing that occurrence. There are two different methods for determining which functions are to be examined. If {arg METHOD}={lisp EDITCALLERS}, {fn EDITCALLERS} is used to search {arg FILES} (see {PageRef Fn EDITCALLERS}). If {arg METHOD}={lisp MASTERSCOPE}, then the Masterscope database is used instead. {arg METHOD}={lisp NIL} defaults to {lisp MASTERSCOPE} if the value of the variable {var DEFAULTRENAMEMETHOD}{index *PRIMARY* DEFAULTRENAMEMETHOD Var} is {lisp MASTERSCOPE} and a Masterscope database exists, otherwise it defaults to {lisp EDITCALLERS}. }} {FnDef {FnName RENAME} {FnArgs OLD NEW TYPES FILES METHOD} {Text First performs {lisp (COPYDEF {arg OLD} {arg NEW} {arg TYPE})} for all {arg TYPE} inside {arg TYPES}. It then calls {fn CHANGECALLERS} to change all occurrences of {arg OLD} to {arg NEW}, and then "deletes" {arg OLD} with {fn DELDEF}. For example, if the user has a function {lisp FOO} which he now wishes to call {lisp FIE}, he simply performs {lisp (RENAME 'FOO 'FIE)}, and {lisp FIE} will be given {lisp FOO}'s definition, and all places that {lisp FOO} are called will be changed to call {lisp FIE} instead. {arg METHOD} is interpreted the same as the {arg METHOD} argument to {fn CHANGECALLERS}, above. }} {FnDef {FnName COMPARE} {FnArgs NAME1 NAME2 TYPE SOURCE1 SOURCE2} {Text Compares the definition of {arg NAME1} with that of {arg NAME2}, by calling {fn COMPARELISTS} ({PageRef Fn COMPARELISTS}) on {lisp (GETDEF {arg NAME1} {arg TYPE} {arg SOURCE1})} and {lisp (GETDEF {arg NAME2} {arg TYPE} {arg SOURCE2})}, which prints their differences on the terminal. For example, if the current value of the variable {lisp A} is {lisp (A B C (D E F) G)}, and the value of the variable {lisp B} on the file {lisp FOO} is {lisp (A B C (D F E) G)}, then: {lispcode _(COMPARE 'A 'B 'VARS 'CURRENT 'FOO) A from CURRENT and B from TEST differ: (E -> F) (F -> E) T} }} {FnDef {FnName COMPAREDEFS} {FnArgs NAME TYPE SOURCES} {Text Calls {fn COMPARELISTS} ({PageRef Fn COMPARELISTS}) on all pairs of definitions of {arg NAME} as a {arg TYPE} obtained from the various {arg SOURCES} (interpreted as a list of source specifications). }} }{End SubSec Functions for Manipulating Typed Definitions} {Begin SubSec Defining New File Package Types} {Title Defining New File Package Types} {Text {index *PRIMARY* Defining file package types} All manipulation of typed definitions in the file package is done using the type-independent functions {fn GETDEF}, {fn PUTDEF}, etc. Therefore, to define a new file package type, it is only necessary to specify (via the function {fn FILEPKGTYPE}) what these functions should do when dealing with a typed definition of the new type. Each file package type has the following properties, whose values are functions or lists of functions: Note: These functions are defined to take a {arg TYPE} argument so that the user may have the same function for more than one type. {Def {Type (File Package Type Property)} {Name GETDEF} {Text Value is a function of three arguments, {arg NAME}, {arg TYPE}, and {arg OPTIONS}, which should return the current definition of {arg NAME} as a type {arg TYPE}. Used by {fn GETDEF} ({PageRef Fn GETDEF}), which passes its {arg OPTIONS} argument. If there is no {lisp GETDEF} property, a file package command for dumping {arg NAME} is created (by {fn MAKENEWCOM}). This command is then used to write the definition of {arg NAME} as a type {arg TYPE} onto the file {lisp FILEPKG.SCRATCH}{index FILEPKG.SCRATCH (file)} (in Interlisp-D, this file is created on the {lisp {bracket CORE}} device). This expression is then read back in and returned as the current definition. {note if GETDEF prop is T (FNS, VARS, etc), this is handled by code in GETDEFCURRENT} Note: In some situations, the function {fn HASDEF} ({PageRef Fn HASDEF}) needs to call {fn GETDEF} to determine whether a definition exists. In this case, {arg OPTIONS} will include the litatom {lisp HASDEF}, and it is permissable for a {lisp GETDEF} function to return {lisp T} or {lisp NIL}, rather than creating a complex structure which will not be used. }} {Def {Type (File Package Type Property)} {Name NULLDEF} {Text The value of the {lisp NULLDEF} property is returned by {fn GETDEF} ({PageRef Fn GETDEF}) when there is no definition and the {lisp NOERROR} option is supplied. For example, the {lisp NULLDEF} of {lisp VARS} is {lisp NOBIND}. }} {Def {Type (File Package Type Property)} {Name FILEGETDEF} {Text This enables the user to provide a way of obtaining definitions from a file that is more efficient than the default procedure used by {fn GETDEF} ({PageRef Fn GETDEF}). Value is a function of four arguments, {arg NAME}, {arg TYPE}, {arg FILE}, and {arg OPTIONS}. The function is applied by {fn GETDEF} when it is determined that a typed definition is needed from a particular file. The function must open and search the given file and return any {arg TYPE} definition for {arg NAME} that it finds. }} {Def {Type (File Package Type Property)} {Name CANFILEDEF} {Text If the value of this property is non-{lisp NIL}, this indicates that definitions of this file package type are not loaded when a file is loaded with {fn LOADFROM} ({PageRef Fn LOADFROM}). The default is {lisp NIL}. Initially, only {lisp FNS} has this property set to non-{lisp NIL}. }} {Def {Type (File Package Type Property)} {Name PUTDEF} {Text Value is a function of three arguments, {arg NAME}, {arg TYPE}, and {arg DEFINITION}, which should store {arg DEFINITION} as the definition of {arg NAME} as a type {arg TYPE}. Used by {fn PUTDEF} ({PageRef Fn PUTDEF}). }} {Def {Type (File Package Type Property)} {Name HASDEF} {Text Value is a function of three arguments, {arg NAME}, {arg TYPE}, and {arg SOURCE}, which should return {lisp (OR {arg NAME} T)} if {arg NAME} is the name of something of type {arg TYPE}. {arg SOURCE} is as interpreted by {fn HASDEF} ({PageRef Fn HASDEF}), which uses this property. }} {Def {Type (File Package Type Property)} {Name EDITDEF} {Text Value is a function of four arguments, {arg NAME}, {arg TYPE}, {arg SOURCE}, and {arg EDITCOMS}, which should edit the definition of {arg NAME} as a type {arg TYPE} from the source {arg SOURCE}, interpreting the edit commands {arg EDITCOMS}. If sucessful, should return {arg NAME} (or a spelling-corrected {arg NAME}). If it returns {lisp NIL}, the "default" editor is called. Used by {fn EDITDEF} ({PageRef Fn EDITDEF}). }} {Def {Type (File Package Type Property)} {Name DELDEF} {Text Value is a function of two arguments, {arg NAME}, and {arg TYPE}, which removes the definition of {arg NAME} as a {arg TYPE} that is currently in effect. Used by {fn DELDEF} ({PageRef Fn DELDEF}). }} {Def {Type (File Package Type Property)} {Name NEWCOM} {Text Value is a function of four arguments, {arg NAME}, {arg TYPE}, {arg LISTNAME}, and {arg FILE}. Specifies how to make a new (instance of a) file package command to dump {arg NAME}, an object of type {arg TYPE}. The function should return the new file package command. Used by {fn ADDTOFILE} and {fn SHOWDEF}. If {arg LISTNAME} is non-{lisp NIL}, this means that the user specified {arg LISTNAME} as the filevar in his interaction with {fn ADDTOFILES?} (see {PageRef Tag FileVars}). If no {lisp NEWCOM} is specified, the default is to call {fn DEFAULTMAKENEWCOM},{index DEFAULTMAKENEWCOM FN} which will construct and return a command of the form {lisp ({arg TYPE} {arg NAME})}. {fn DEFAULTMAKENEWCOM} can be advised or redefined by the user. }} {Def {Type (File Package Type Property)} {Name WHENCHANGED} {Text Value is a list of functions to be applied to {arg NAME}, {arg TYPE}, and {arg REASON} when {arg NAME}, an instance of type {arg TYPE}, is changed or defined (see {fn MARKASCHANGED}, {PageRef Fn MARKASCHANGED}). Used for various applications, e.g. when an object of type {lisp I.S.OPRS} changes, it is necessary to clear the corresponding translatons from {var CLISPARRAY}. The {lisp WHENCHANGED} functions are called before the object is marked as changed, so that it can, in fact, decide that the object is {it not} to be marked as changed, and execute {lisp (RETFROM 'MARKASCHANGED)}. Note: For backwards compatibility, the {arg REASON} argument passed to {lisp WHENCHANGED} functions is either {lisp T} (for {lisp DEFINED}) and {lisp NIL} (for {lisp CHANGED}). }} {Def {Type (File Package Type Property)} {Name WHENFILED} {Text Value is a list of functions to be applied to {arg NAME}, {arg TYPE}, and {arg FILE} when {arg NAME}, an instance of type {arg TYPE}, is added to {arg FILE}. }} {Def {Type (File Package Type Property)} {Name WHENUNFILED} {Text Value is a list of functions to be applied to {arg NAME}, {arg TYPE}, and {arg FILE} when {arg NAME}, an instance of type {arg TYPE}, is removed from {arg FILE}. }} {Def {Type (File Package Type Property)} {Name DESCRIPTION} {Text Value is a string which describes instances of this type. For example, for type {lisp RECORDS}, the value of {lisp DESCRIPTION} is the string {lisp "record declarations"}. }} The function {fn FILEPKGTYPE} is used to define new file package types, or to change the properties of existing types. Note that it is possible to redefine the attributes of system file package types, such as {lisp FNS} or {lisp PROPS}. {FnDef {FnName FILEPKGTYPE} {FnArgs TYPE PROP{SUB 1} VAL{SUB 1} {ellipsis} PROP{SUB N} VAL{SUB N}} {Type NOSPREAD} {Text Nospread function for defining new file package types, or changing properties of existing file package types. {arg PROP{sub i}} is one of the property names given above; {arg VAL{sub i}} is the value to be given to that property. Returns {arg TYPE}. {lisp (FILEPKGTYPE {arg TYPE} {arg PROP})} returns the value of the property {arg PROP}, without changing it. {lisp (FILEPKGTYPE {arg TYPE})} returns an alist of all of the defined properties of {arg TYPE}, using the property names as keys. {index *PRIMARY* Synonyms for file package types} Note: Specifying {arg TYPE} as the litatom {lisp TYPE} can be used to define one file package type as a synonym of another. For example, {lisp (FILEPKGTYPE 'R 'TYPE 'RECORDS)} defines {lisp R} as a synonym for the file package type {lisp RECORDS}. }} }{End SubSec Defining New File Package Types} }{End SubSec File Package Types} ?1(DEFAULTFONT 1 (GACHA 10) (GACHA 8) (TERMINAL 8)) ?1(DEFAULTFONT 1 (GACHA 10) (GACHA 8) (TERMINAL 8)) ?1(DEFAULTFONT 1 (GACHA 10) (GACHA 8) (TERMINAL 8)) ?1(DEFAULTFONT 1 (GACHA 10) (GACHA 8) (TERMINAL 8)) w´w´zº