User Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cl:functions:coerce [2019/06/15 02:00]
cl:functions:coerce [2019/08/19 17:00] (current)
Line 1: Line 1:
 +====== Function COERCE ======
 +
 +====Syntax====
 +  * **coerce** //object result-type//​ → //result//
 +
 +====Arguments and Values====
 +  * //object// - an //​[[CL:​Glossary:​object]]//​.
 +  * //​result-type//​ - a //​[[CL:​Glossary:​type specifier]]//​.
 +  * //result// - an //​[[CL:​Glossary:​object]]//,​ of //​[[CL:​Glossary:​type]]//​ //​result-type//​ except in situations described in \secref\RuleOfCanonRepForComplexRationals.
 +
 +====Description====
 +//​[[CL:​Glossary:​coerce|Coerces]]//​ the //object// to //​[[CL:​Glossary:​type]]//​ //​result-type//​.
 +
 +If //object// is already of //​[[CL:​Glossary:​type]]//​ //​result-type//,​ the //object// itself is returned, regardless of whether it would have been possible in general to coerce an //​[[CL:​Glossary:​object]]//​ of some other //​[[CL:​Glossary:​type]]//​ to //​result-type//​.
 +
 +Otherwise, the //object// is //​[[CL:​Glossary:​coerce|coerced]]//​ to //​[[CL:​Glossary:​type]]//​ //​result-type//​ according to the following rules:
 +
 +===sequence===
 +If the //​result-type//​ is a //​[[CL:​Glossary:​recognizable subtype]]// of **[[CL:​Types:​list]]**,​and the //​[[CL:​Glossary:​object]]//​ is a //​[[CL:​Glossary:​sequence]]//,​ then the //result// is a //​[[CL:​Glossary:​list]]//​ that has the //​[[CL:​Glossary:​same]]//​ //​[[CL:​Glossary:​element|elements]]//​ as //object//.
 +
 +If the //​result-type//​ is a //​[[CL:​Glossary:​recognizable subtype]]// of **[[CL:​Types:​vector]]**,​and the //​[[CL:​Glossary:​object]]//​ is a //​[[CL:​Glossary:​sequence]]//,​ then the //result// is a //​[[CL:​Glossary:​vector]]//​ that has the //​[[CL:​Glossary:​same]]//​ //​[[CL:​Glossary:​element|elements]]//​ as //object//. If //​result-type//​ is a specialized //​[[CL:​Glossary:​type]]//,​ the //result// has an //​[[CL:​Glossary:​actual array element type]]// that is the result of //​[[CL:​Glossary:​upgrade|upgrading]]//​ the element type part of that //​[[CL:​Glossary:​specialized]]//​ //​[[CL:​Glossary:​type]]//​. If no element type is specified, the element type defaults to **[[CL:​Types:​t]]**. If the //​[[CL:​Glossary:​implementation]]//​ cannot determine the element type, an error is signaled.
 +
 +===character===
 +If the //​result-type//​ is **[[CL:​Types:​character]]** and the //​[[CL:​Glossary:​object]]//​ is a //​[[CL:​Glossary:​character designator]]//,​ the //result// is the //​[[CL:​Glossary:​character]]//​ it denotes.
 +
 +===complex===
 +If the //​result-type//​ is **[[CL:​Types:​complex]]** and the //​[[CL:​Glossary:​object]]//​ is a //​[[CL:​Glossary:​real]]//,​ then the //result// is obtained by constructing a //​[[CL:​Glossary:​complex]]//​ whose real part is the //​[[CL:​Glossary:​object]]//​ and whose imaginary part is the result of //​[[CL:​Glossary:​coercing]]//​ an //​[[CL:​Glossary:​integer]]//​ zero to the //​[[CL:​Glossary:​type]]//​ of the //​[[CL:​Glossary:​object]]//​ (using **coerce**). (If the real part is a //​[[CL:​Glossary:​rational]]//,​ however, then the result must be represented as a //​[[CL:​Glossary:​rational]]//​ rather than a //​[[CL:​Glossary:​complex]]//;​ see section {\secref\RuleOfCanonRepForComplexRationals}. So, for example, ''​(coerce 3 '​[[CL:​Types:​complex]])''​ is permissible,​ but will return ''​3'',​ which is not a //​[[CL:​Glossary:​complex]]//​.)
 +
 +===float===
 +If the //​result-type//​ is any of **[[CL:​Types:​float]]**,​ **[[CL:​Types:​short-float]]**,​ **[[CL:​Types:​single-float]]**,​ **[[CL:​Types:​double-float]]**,​ **[[CL:​Types:​long-float]]**,​and the //​[[CL:​Glossary:​object]]//​ is a //​[[CL:​Glossary:​real]]//,​ then the //result// is a //​[[CL:​Glossary:​float]]//​ of //​[[CL:​Glossary:​type]]//​ //​result-type//​ which is equal in sign and magnitude to the //​[[CL:​Glossary:​object]]//​ to whatever degree of representational precision is permitted by that //​[[CL:​Glossary:​float]]//​ representation. (If the //​result-type//​ is **[[CL:​Types:​float]]** and //object// is not already a //​[[CL:​Glossary:​float]]//,​ then the //result// is a //​[[CL:​Glossary:​single float]]//.)
 +
 +===function===
 +If the //​result-type//​ is **[[CL:​Types:​function]]**,​and //object// is any //​[[CL:​Glossary:​function name]]// that is //​[[CL:​Glossary:​fbound]]//​ but that is globally defined neither as a //​[[CL:​Glossary:​macro name]]// nor as a //​[[CL:​Glossary:​special operator]]//,​ then the //result// is the //​[[CL:​Glossary:​functional value]]// of //object//.
 +
 +If the //​result-type//​ is **[[CL:​Types:​function]]**,​and //object// is a //​[[CL:​Glossary:​lambda expression]]//,​ then the //result// is a //​[[CL:​Glossary:​closure]]//​ of //object// in the //​[[CL:​Glossary:​null lexical environment]]//​.
 +
 +===t===
 +Any //object// can be //​[[CL:​Glossary:​coerce|coerced]]//​ to an //​[[CL:​Glossary:​object]]//​ of type **[[CL:​Types:​t]]**. In this case, the //object// is simply returned.
 +
 +====Examples====
 +<​blockquote> ​
 +(coerce '(a b c) '​[[CL:​Types:​vector]]) <​r>#​(A B C) </r>
 +(coerce 'a '​[[CL:​Types:​character]]) <​r>#​\A </r>
 +(coerce 4.56 '​[[CL:​Types:​complex]]) <​r>#​C(4.56 0.0) </r>
 +(coerce 4.5s0 '​[[CL:​Types:​complex]]) <​r>#​C(4.5s0 0.0s0) </r>
 +(coerce 7/2 '​[[CL:​Types:​complex]]) <​r>​7/​2 </r>
 +(coerce 0 '​[[CL:​Types:​short-float]]) <​r>​0.0s0 </r>
 +(coerce 3.5L0 '​[[CL:​Types:​float]]) <​r>​3.5L0 </r>
 +(coerce 7/2 '​[[CL:​Types:​float]]) <​r>​3.5 </r>
 +(coerce ([[CL:​Functions:​cons]] 1 2) [[CL:​Types:​t]]) <r>(1 . 2) </r>
 +</​blockquote>​
 +
 +All the following //​[[CL:​Glossary:​forms]]//​ should signal an error:
 +
 +<​blockquote> ​
 +(coerce '(a b c) '​([[CL:​Types:​vector]] * 4)) 
 +(coerce #(a b c) '​([[CL:​Types:​vector]] * 4)) 
 +(coerce '(a b c) '​([[CL:​Types:​vector]] * 2)) 
 +(coerce #(a b c) '​([[CL:​Types:​vector]] * 2)) 
 +(coerce "​foo"​ '​([[CL:​Types:​string]] 2)) 
 +(coerce #(#\a #\b #\c) '​([[CL:​Types:​string]] 2)) 
 +(coerce '(0 1) '​([[CL:​Types:​simple-bit-vector]] 3)) 
 +</​blockquote>​
 +
 +====Affected By====
 +None.
 +
 +====Exceptional Situations====
 +If a coercion is not possible, an error of type **[[CL:​Types:​type-error]]** is signaled.
 +
 +''​(coerce x '​[[CL:​Constant Variables:​nil]])''​ always signals an error of type **[[CL:​Types:​type-error]]**.
 +
 +An error of type **[[CL:​Types:​error]]** is signaled if the //​result-type//​ is **[[CL:​Types:​function]]** but //object// is a //​[[CL:​Glossary:​symbol]]//​ that is not //​[[CL:​Glossary:​fbound]]//​ or if the //​[[CL:​Glossary:​symbol]]//​ names a //​[[CL:​Glossary:​macro]]//​ or a //​[[CL:​Glossary:​special operator]]//​.
 +
 +An error of type **[[CL:​Types:​type-error]]** should be signaled if //​result-type//​ specifies the number of elements and //object// is of a different length.
 +
 +====See Also====
 +  * **[[CL:​Functions:​rational|Function RATIONAL]]**
 +  * **[[CL:​Functions:​floor|Function FLOOT]]**
 +  * **[[CL:​Functions:​char-code|Function CHAR-CODE]]**
 +  * **[[CL:​Functions:​char-int|Function CHAR-INT]]**
 +
 +====Notes====
 +Coercions from //​[[CL:​Glossary:​floats]]//​ to //​[[CL:​Glossary:​rationals]]//​ and from //​[[CL:​Glossary:​ratios]]//​ to //​[[CL:​Glossary:​integers]]//​ are not provided because of rounding problems.
 +
 +<​blockquote> ​
 +(coerce x '​[[CL:​Types:​t]]) ​
 +  ≡ ([[CL:​Functions:​identity]] x) 
 +  ≡ x 
 +</​blockquote>​
 +
 +\issue{FUNCTION-TYPE:​X3J13-MARCH-88} \issue{COERCING-SETF-NAME-TO-FUNCTION:​ALL-FUNCTION-NAMES} \issue{SEQUENCE-TYPE-LENGTH:​MUST-MATCH} \issue{SEQUENCE-TYPE-LENGTH:​MUST-MATCH} \issue{CONCATENATE-SEQUENCE:​SIGNAL-ERROR} \issue{CHARACTER-LOOSE-ENDS:​FIX} \issue{REAL-NUMBER-TYPE:​X3J13-MAR-89}