Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

Maxima/Identifiers

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

"One quick way to check on name conflicts is to keep the html Maxima help manual up in a separate window, and have the Index panel available to type in a name you want to use. The painful way to check on name conflicts is to wait for Maxima to give you a strange error message as to why what you are trying to do won’t work. If you get strange results, try changing the names of your variables and or functions. An important fact is that Maxima is case sensitive, so you can avoid name conflicts by capitalizing the names of your user defined Maxima functions. Your Solve will not conflict with Maxima’s solve."Maxima by Example: Ch. 1, Introduction to Maxima by Edwin L. Woollett – Edwin L. Woollett The Maxima Namespace The topic of the namespace system used by Maxima is in a sense more relevant to programming expressions. However, since the nature of the Maxima namespace system is also relevant to Maxima identifiers as used in this book, and also as used routinely in the composition of Maxima expressions in general, and particularly mathematical expressions, some of the technical detail is provided here for the purpose of describing the role of identifiers. It is worth repeating here that in this book, for reasons of simplicity, the use of the term identifier is meant to encapsulate names used for various purposes as described below. The Maxima CAS namespace system is best characterized as case-sensitive for user-defined identifiers but case-insensitive (normalized to lowercase) for built-in operators (functions) and constants, with a flat global namespace for identifiers: Case Sensitivity: Maxima provides a case-sensitive namespace system where identifiers, functions, and operators are distinct entities based on their spelling. Maxima distinguishes between upper and lower case for user-defined identifiers and functions; for example, foo, Foo, and FOO are treated as distinct identifiers. Built-in Normalization: All built-in operators (e.g., sin, cos) and constants (e.g., %e, %pi) have lowercase names only.  Typing SIN(x) or Sin(x) causes Maxima to assume the user is referring to a user-defined function rather than the built-in sine function. Namespace Structure: The system uses a single global namespace where identifiers and functions persist until the session ends or are explicitly removed (e.g., via the kill() command).  There is no modular scoping for standard identifiers. However, Maxima maintains specific exceptions for predefined mathematical operators (functions) and constants: Built-in (predefined) operators (functions) (e.g., sin, cos, log) are mapped to uppercase versions internally (e.g., SIN, COS), allowing users to call them with either case, though lowercase is recommended for clarity. Built-in constants (e.g., %e, %pi, %i, %gamma) are strictly lowercase and must be entered exactly as such. System names related to session history (input or output labels) also use the % prefix and are case-sensitive. Users are advised to use lowercase for user-defined names and functions to ensure readability and avoid conflicts with the internal uppercase mapping of standard mathematical operators. The namespace system in Maxima is fundamentally built upon its underlying Lisp implementation, creating a unique environment where case sensitivity, symbol translation rules, and special prefixes dictate how values for identifiers and functions are stored and accessed. The namespace utilizes dynamic scoping rather than lexical scoping for most operations, which impacts variable visibility and modification: Dynamic Scope: Identifiers defined outside a function are global in scope and can be inadvertently modified by functions if the identifiers are the same, unless explicitly made local. For instance, a loop identifier i in a global context might be overwritten by a function using i if not properly scoped. A reference to a defined Maxima function accesses the values of identifiers based on the environment of the function that exists at the point of reference. If an identifier local to the function exists, the value of that identifier is used. Otherwise, Maxima will attempt to find the value of the referenced identifier outside of the the local scope of the function in the global namespace. This means that identifiers are by default global in scope, and that users must account for this contingency when defining and referencing functions. Refer to the Maxima documentation for the descriptions of the block ( ) and local ( ) operators for information related to the scope of identifiers. Global Persistence: By default, all user identifiers reside in a single global namespace. They persist until the session ends or are explicitly removed. Identifier Removal Mechanisms: kill(symbol): Completely removes the value, function definition, array, and properties of an identifier. remvalue(symbol): Removes only the assigned value of the identifier, leaving function definitions or array properties intact. kill(all): Clears all user-defined identifiers from the namespace. The operator reset is used to reset internal Maxima built-in global "flags" or option identifiers to their defaults. Identifiers Symbols, variables, and identifiers do not technically refer to the same thing in Maxima, though they are closely related and often overlap in the way to which they are referred in typical use. Here is the breakdown of how Maxima distinguishes between them: Identifiers (names) Identifiers are syntactic names. They are the characters users choose as names, or have been chosen as built-in. Identifiers typically name variables, functions, labels, operators. Symbols (objects in memory) The underlying programming language of Maxima is Lisp. A symbol is a fundamental data type in Lisp. When Maxima parses an expression and encounters an identifier, Maxima refers to or creates a corresponding symbol object "under the hood" in Lisp. These symbol objects can hold a value, a function definition, and various properties (like whether it is declared integer, constant, etc.) all at the same time. Example: The identifier named x refers to the symbol object x which may have a value of itself, or an expression that is a different value, and also declared properties. Variables (symbols with role that references values or properties) Variables are symbols being used to store or represent an expression value that can be changed. When a symbol is encountered that has an expression value that can be changed ( a variable in the programming sense of the term), but the expression value is simply the name of the symbol itself, then it can be considered a variable in the mathematical sense of the word. When a symbol is encountered that has an expression value that can be changed ( a variable in the programming sense of the term), but the expression value is some expression other than the name of the symbol itself, then it should not be considered a variable in the mathematical sense of the word. Rather the symbol in this case, although a variable because it is a symbol that can be changed, serves simply as a name for its value – an alias. Examples: x + 1 The value of the expression x + 1 depends on the value of x. If x has a value of itself (x is x) then the identifier x names a symbol that can be changed – it is a variable – and therefore it is a variable in the programming sense of the term, and can be considered a variable in the mathematical sense of the term. x : 5 x + 1 is 6 If x has a value other than itself (x is 5) then the identifier x names a symbol that can be changed – it is a variable – and therefore it is a variable in the programming sense of the term, but should not be considered a variable in the mathematical sense of the term. +ComparisonConceptWhat it isMaxima ExamplesAnalogous toIdentifiercharacters read as Maxima inputnamename of a person on a name tag "Hi! My name is John."Symbolunderlying data object in memoryentity name which can have properties, values, or functions associated with itan actual person wearing a name tagVariablerole a symbol has for representing a value/* name symbol has the value name */ name; /* name symbol has the value "John" */ name : "John"; - some variable person acting in some job role - a specific person acting in their job role Why these distinctions matter in Maxima Because Maxima is a computer algebra system (CAS), and not a general-purpose programming language, you can refer to symbols without assigning values to them. For example:(%i1) x + x; (%o1) 2*xIn this example, x is an identifier associated a symbol with no assigned value, and consequently may act as a mathematical variable. These distinctions also matter due to the fact that these terms are commonly used in the Maxima Manual and elsewhere. Sometimes understanding these distinctions matter, sometimes they don't matter, and sometimes they are used synonymously – for better or worse. In any case, in the context of typical usage, identifiers are used to compose Maxima expressions, and expressions, particularly mathematical expressions, are what matters most from the Maxima user point of view. Names, symbols, words, variables, constants, literals, labels, flags, options, and identifiers are all technical terms the meaning of which may depend on the context in which these terms are used. In this book, for the sake of simplicity, at the expense of possibly being technically imprecise, the term identifier is used for names in the broadest practical sense as follows: A name that has a value of itself – (a is a) is true, or A name that has a value of an expression other than itself – (a is b) and (a is not a) is true. (%i1) y; /* The value of y is y, y is a name for itself. */ (%o1) y (%i2) y : f(x); /* y is assigned an expression */ (y) f(x) (%i3) y; /* The value of y is f(x), y is a name for f(x). */ (%o3) f(x)This means that in this book, identifiers refer to names for: symbols, words, variables, constants, literals, labels, flags, options, and so forth, and that if distinctions are necessary, it should be provided by the context in which the term identifier is used. Reserved Words The Maxima Manual provides the following caveat regarding reserved words:"There are a number of reserved words which should not be used as variable names. Their use would cause a possibly cryptic syntax error." integrate next from diff in at limit sum for and elseif then else do or if unless product while thru step Apart from these Maxima reserved words, there is relative freedom in the choice of identifiers. Identifier Composition Rules: Maxima identifiers follow specific lexical rules: Allowed Characters: Alphabetic characters (A-Z, a-z), digits (0-9), and the underscore (_). Special Characters: Any special character can be included if preceded by a backslash (\). For example, a\+b is a valid single identifier. Starting with Digits: An identifier can start with a digit if escaped (e.g., \1st_var). Unicode Support: Modern versions of Maxima (and specifically interfaces like wxMaxima) support Unicode characters in identifiers, treating them as alphabetic characters without needing escape sequences, provided the underlying Lisp and font support them. Characters Declared Alphabetic: The declare (character, alphabetic) operator can be used to in order to use a character in composing an identifier that otherwise would not be considered as alphabetic. It seems to be the case that, unless otherwise noted, there are no naming conventions or a style guide for Maxima. So in general, it is up to the user to decide on the composition of identifiers. Note that identifiers may be used that are one or more characters that comprise the alphabetic characters, plus the digits 0 through 9, plus any other character preceded by the backslash ( \ ) escape character including the space character. Note however, that the \ must be entered for each reference to the identifier. A numeral may be the first character of an identifier if it is preceded by a backslash. Numerals which are the second or later characters need not be preceded by a backslash. The alphabetic characters are initially %, _, and the lower and upper case letters of the alphabet - that is, all characters for which the Lisp function ALPHA-CHAR-P returns true. Characters may be declared alphabetic by the declare (character, alphabetic) operator. If so declared, they need not be preceded by a backslash in an identifier. However, the use of the declare (character, alphabetic) operator may cause unintended and unwanted side effects depending on the character, so this operator for this purpose should be used with that in mind if at all. Atoms and Symbols As discussed,the term symbol and identifier are frequently used in the context of names. The use of the term symbol can be attributed, as much else in Maxima, to its Lisp orientation. In Maxima, atom() and symbolp() serve different purposes regarding object classification, though their outputs often overlap for names. atom(v) returns true if v is an atom and false otherwise.  In Maxima, atoms include numbers, strings, names (symbols), and nil. Expressions (which have an operator and arguments) are not atoms. For example, atom(5) is true, atom(x) is true, but atom(x+1) is false because it is an expression with the operator +. symbolp(v) returns true only if v is a symbol (a name).  It returns false for numbers, strings, or any other atomic type that is not a name.  For example, symbolp(x) is true, but symbolp(5) is false. The key difference is that atom() is a broader predicate that includes symbols, numbers, and strings, while symbolp() is specific to symbolic names. Examples: /* Atom checks */ (%i4) atom(7); /* true: 7 is an atomic number */ (%o4) true (%i5) atom(x); /* true: x is an atomic symbol */ (%o5) true (%i6) atom("hello there"); /* true: "hello there" is an atomic string */ (%o6) true (%i7) atom(x+1); /* false: x+1 is an expression */ (%o7) false (%i8) symbolp(7); /* false: 7 is not a symbol */ (%o8) false (%i9) symbolp(\7); /* true: 7 is now a symbol */ (%o9) true (%i10) symbolp(x); /* true: x is a symbol */ (%o10) true (%i11) symbolp(x+1); /* false: x+1 is a not a symbol */ (%o11) false (%i12) symbolp(x\+1); /* true: x\+1 is a symbol */ (%o12) true (%i13) symbolp("hello there"); /* false: "hello there" is not a symbol */ (%o13) false (%i14) symbolp(hello\ there); /* true: hello\ there is now a symbol */ (%o14) true Summary Table: OperatorReturns true for...Returns false for...atom()Numbers, Identifiers, Strings, nilExpressions (e.g., x+1, sin(x))symbolp()Symbols (names of symbols)Numbers, Strings, Expressions, nil Atoms are further categorized into integers, floats, strings, or identifiers. Use atom() to distinguish between atomic data and composite expressions, and symbolp() to specifically identify symbolic names. In attempting to be technically precise in the use of these various terms, it is often the case that the user becomes immersed in a confusing sea of technical jargon. On the other hand, in attempting to be clear and simple, there is the risk that some subjective or objective technical standards fail to be met. In this book, for the sake of clarity and simplicity, the term identifier is used for names and symbols in the broadest practical sense. Unicode Support: As was mentioned previously, versions of Maxima, and specifically the wxMaxima GUI, support Unicode characters in identifiers, treating them as alphabetic characters without the need to be escaped, provided the underlying Lisp implementation and font support them. This support extends the set of characters available for use in composing identifiers. This support can be useful in using Greek letters and other mathematical symbols. For example:(%i5) Θ(s,r):= s/r; (%o5) Θ(s,r):=s/r (%i6) Θ(%pi/2,4); /* radians as a function of arc length and radius */ (%o6) %pi/8Unicode can also be used in other ways in expressions:(%i7) declare(ℝ, feature); /* make ℝ a feature */ (%o7) done /* define a function to test identifiers for feature ℝ */ (%i8) ℝ(x):= block( [q], if not symbolp(x) then q:sconcat(x," is not an indentifier") elseif featurep(x, ℝ) then q:concat(x, " ∈ ℝ") else q:concat(x, " ∉ ℝ"), return (q) )$ (%i9) declare(x,ℝ); /* make ℝ a feature of identifier x */ (%o9) done (%i10) ℝ(x); /* check x for feature ℝ */ (%o10) x ∈ ℝ (%i11) ℝ(w); /* check w for feature ℝ */ (%o11) w ∉ ℝ (%i12) ℝ(3); /* check 3 for feature ℝ */ (%o12) 3 is not an indentifierUsers should be aware of some aspects of using Unicode in the context of Maxima. First, apart from the wxMaxima GUI, using Unicode characters is likely to be a "cut-and-paste" operation using a character map of some kind. wxMaxima has built-in Unicode support which makes using these characters simple. Second, there can be some anomalous behavior. For example:(%i14) ℃; /* This Unicode character ℃ (2103) is an acceptable symbol */ (%o14) ℃ (%i15) symbolp(℃); /* Maxima likes ℃ */ (%o15) true /* This Unicode character ℉ (2109) is an acceptable symbol */ (%i16) symbolp(℉); (%o16) true /* This Unicode character ° (00B0) is an acceptable symbol */ (%i17) symbolp(°) (%o17) true /* Maxima does not like this ° (00B0) character with another one */ (%i18) symbolp(°R); incorrect syntax: R is not an infix operator symbolp(°R) ^ /* Maxima likes this ° (00B0) character if escaped */ (%i19) symbolp(\°R); (%o19) true Features: The foregoing example demonstrates that features can be associated with identifiers.(%i10) features; (%o10) [integer,noninteger,even,odd,rational,irrational,real, imaginary,complex,analytic,increasing,decreasing,oddfun evenfun,posfun,constant,commutative,lassociative, rassociative,symmetric,antisymmetric,integervalued,ℝ]All of these features are built-in to Maxima except the last one – ℝ. ℝ is a user-defined feature. Maxima recognizes certain mathematical properties of functions and identifiers. These properties are called "features". The operator declare(x,foo) associates the feature foo with the function or identifier x. The operator declare(foo, feature) declares a new feature foo. For example, declare(ℝ, feature) declares ℝ as a user-defined feature. The predicate operator featurep(x, ℝ returns true if x has the ℝ feature, and false otherwise. Properties: In addition to features, properties can be attributed to identifiers using the put (atom, value, indicator) operator or the qput (atom, value, indicator) operator. The terminology used with these operators can be confusing. These operators attribute a property using the argument named indicator and assign a value to the indicator using the argument named value to that indicator. The difference between these two operators is that put evaluates arguments and qput does not. The Maxima documentation explains as follows: put (atom, value, indicator) Assigns value to the property (specified by indicator) of atom.  indicator may be the name of any property, not just a system-defined property. rem reverses the effect of put. put evaluates its arguments. put returns value. qput (atom, value, indicator) Assigns value to the property (specified by indicator) of atom. This is the same as put, except that the arguments are quoted.What "quoted" means in this context is that the evaluation of the arguments is suppressed. The operator get(atom, indicator) returns the property indicated by indicator associated with the identifier (atom) or returns false if atom doesn’t have the property indicator. The operator get evaluates its arguments. The fog of this word salad can be lifted by way of an example. The following from the Maxima Manual exemplifies the use of the put and get operators:(%i11) put (%e, 'transcendental, 'type); (%o11) transcendental (%12) put (%pi, 'transcendental, 'type); (%o12) transcendental (%i13) put (%i, 'algebraic, 'type); (%o13) algebraic (%i14) typeof (expr) := block ([q], if numberp (expr) then return ('algebraic), if not atom (expr) then return (maplist ('typeof, expr)), q: get (expr, 'type), if q=false then errcatch (error(expr,"is not numeric.")) else q)$ (%i15) typeof (2*%e + x*%pi); x is not numeric. (%o15) [[transcendental,[]],[algebraic,transcendental]] (%i16) typeof (2*%e + %pi); (%o16) [transcendental,[algebraic,transcendental]]These expressions provide examples of the use of put and get operators. The indicator for the property used is quoted ( 'type ) presumably to prevent its evaluation in order to prevent a possible clash with a Maxima system identifier with the same name. An identifier can have multiple attributed properties. The same property can be attributed to different identifiers with different values. This example also demonstrates the recursive use of the user-defined function typeof. Maxima System Constants: Maxima provides built-in identifiers used to reference some frequently used constants. Among these are %e, %i, %gamma, and %phi, as well as others. Refer to the Maxima documentation for the full list of built-in constants and the related technical details. Maxima System Labels: The following table summarizes the built-in identifier labels for input and output expressions: +Maxima Input and Output LabelsLabelValue%last output expression %ininput expression as labeled%onoutput expression as labeled The value of n within these labels is generated automatically and sequentially by Maxima. The values of n are numerals for the natural numbers starting at 1. These labels can serve as a sort of handy shorthand as identifiers for referencing expressions. However, users should be aware that reliance on these labels in certain cases can result in unexpected and unwanted side-effects, as well as a negative effect on the readability of saved expressions. The system labels %z7 and %z9 represent any arbitrary integer value. These labels also are automatically generated by Maxima, and typically appear in the output of equation-solving functions (such as solve) when the solution involves periodic or multi-valued mathematical expressions, such as complex logarithms or roots. They serve as integer parameters to indicate that the solution is valid for any integer value assigned to them. Maxima System Flags: There are built-in Maxima system identifiers that serve special purposes. These identifiers may be referred to as option variables or flags. Frequently, these flags have the value of true or false , with one or the other as the default value. These flags are relatively many in number, and too numerous to exemplify here. One flag that can serve as an example is simp:(%i17) simp; /* The default value of simp is true */ (%o17) true (%i18) 3+4; /* simplification is active */ (%o18) 7 (%i19) 21/7; /* simplification is active */ (%o19) 3 (%i20) simp:false; /* the value of simp is assigned false */ (simp) false (%i21 3+4; /* simplification is not active */ (%o21) 3+4 (%i22) 21/7; /* simplification is not active */ (%o22) 21/7 It may be a counter-intuitive recognition that calculations like these simple examples are a matter of simplification and not evaluation, but that is the case even if more complex expressions are involved.(%i23) x:3; /* identifier x is assigned the value of 3 */ (x) 3 (%i24) x; /* the value of x is 3 by evaluation */ (%o24) 3 (%i25) x+4; /* this expression is evaluated but not simplified */ (%o25) 3+4Assigning the simp flag to true allows simplification to occur:(%i26) simp:true; /* the simp flag is assigned true */ (simp) true (%i27) x+4; /* this expression is evaluated and now simplified */ (%o27) 7