Clisp bracket operators are defined by having the value of the {prop CLISPTYPE} property be the atom {lisp BRACKET} for both left and right brackets, e.g. for both {lisp <} and {lisp >}.  See discussion of {prop CLISPBRACKET} below.



{PropDef {Name CLISPBRACKET}
{Text
Used for defining {lisp CLISP} bracket operators.  This property must be on the property list of both the left and right brackets, and also on the property list of any of the functions that expressions involving the brackets translate to (to enable clispifying).  For the latter, the property value is simply the left bracket, e.g. {lisp <}.  For the brackets themselves, {fn CAR} of the property value is the left bracket, {fn CADR} the right bracket, and {fn CDDR} a list in property list format.  The following properties are recognized:

{Begin LabeledList properties of CLISPBRACKET property list}

{Label {lisp DWIMIFY}}
{Item
function to be called to dwimify the construct:  If the bracket is a unary operator, the function will be applied to the list consisting of the (dwimified) segment between the matching brackets.  If the bracket is not a unary operator, the function will be applied to the (dwimified) expression to the left of the bracket and the (dwimified) segment between the brackets.  (See example below.)
}

{Label {lisp CLISPIFY}}
{Item
(optional) function to be called when clispifying.{foot
If the {lisp CLISPIFY} property is not present, {fn CLISPIFY}ing will consist of, for unary brackets, {fn CLISPIFY}ing {fn CDR} of the form, inserting the separator if any between each element, and surrounding the result with the brackets.  For brackets that are not unary operators, {fn CADR} of the form is clispified and placed to the left of the brackets, and {fn CDDR} of the form treated as above.
}{comment endfootnote}
}

{Label {lisp SEPARATOR}}
{Item
(optional) character to be split from any atoms but otherwise unprocessed, e.g. for {lisp <} and {lisp >}, the separator is {lisp !}
}

{End LabeledList properties of CLISPBRACKET property list}

}}




For example, to define {lisp {lbracket} {rbracket}} as a bracket which translates to {lisp ELT} in the case of a single expression, and {lisp MULTI-ELT} for more than one:


{lispcode
←PUTPROP({lbracket} CLISPTYPE BRACKET)
←PUTPROP({rbracket} CLISPTYPE BRACKET)
←PUTPROP({lbracket} CLISPBRACKET ({lbracket} {rbracket} SEPARATOR , DWIMIFY FOO]
←PUTPROP({rbracket} CLISPBRACKET ({lbracket} {rbracket} SEPARATOR , DWIMIFY FOO]
←DEFINEQ[(FOO (A LST)
	(IF (MEMB ', LST)
		THEN <'MULTI-ELT A (FOR X IN LST COLLECT X WHEN X~=',)>
		ELSE <'ELT A ! LST>]
←(NCONC CLISPCHARS '({lbracket} {rbracket} ,))
←(SETQ CLISPCHARRAY (MAKEBITTABLE CLISPCHARS))
}


Then, {lisp X:1{bracket N-1}} will dwimify to {lisp (ELT (CAR X) (SUB1 N))}
and {lisp Z{bracket N,M}} will dwimify to {lisp (MULTI-ELT Z N M)}


To enable clispifying,

{lispcode
←PUTPROP(ELT CLISPBRACKET {lbracket})
←PUTPROP(MULTI-ELT CLISPBRACKET {lbracket})
}


Then, {lisp (MULTI-ELT (CADR A) (IQUOTIENT (SUB1 N) 2)) I)} will clispify to {lisp A:2{bracket (N-1)/2,I}}.


{Begin Note}
Date: 29 JUN 1978 1642-PDT
From: TEITELMAN
Subject: BRACKETS IN CLISP
To:   CROCKER at ISIE, KAPLAN

havent worked out all the details yet but

(1) would you want to translate a bracket one way sometimes and another way another time, e.g. translate {bracket 1,2} differently than {bracket 1}, like use ELT for one and MULTI-ELT or some such for another

(2) would you ever want to use more than one "separator" inside of a bracket, such as ,'s mixed with
;

(3) if the latter, would it be tolerable to have to do your own clispifying on this particular car of form via a clispifyuserfn? i.e. suppose i clispified by simply keying off car of form, and if it was a bracket translator, put in the brackets (preceded by the first operand if not a unaryop) and put in the ,'s or ;'s or whatever was specified as the "separator" .

e.g. supose we define {bracket} as a binary bracket operator so that A{bracket 1} goes to (ELT A 1), and A{bracket 1,2} goes to (MULTIELT A 1 2),  then ELT and MULTIELT would always clispify as A{bracket 1} and A{bracket 1,2}  but if you wanted A{bracket 1,2;3} to mean something else (which is acceptable since you get to specify a translation function), then you would have to handle your own clispifying because i wouldnt know how to put in , or ;.

basically i will let you specify "separator" characters and explode them out but not do anything else with them when dwimifying, and i will put them back in when
clispifying.
{End Note}