LISP – Input & Output

LISP – Input & Output ”; Previous Next Common LISP provides numerous input-output functions. We have already used the format function, and print function for output. In this section, we will look into some of the most commonly used input-output functions provided in LISP. Input Functions The following table provides the most commonly used input functions of LISP − Sr.No. Function & Description 1 read & optional input-stream eof-error-p eof-value recursive-p It reads in the printed representation of a Lisp object from input-stream, builds a corresponding Lisp object, and returns the object. 2 read-preserving-whitespace & optional in-stream eof-error-p eof-value recursive-p It is used in some specialized situations where it is desirable to determine precisely what character terminated the extended token. 3 read-line & optional input-stream eof-error-p eof-value recursive-p It reads in a line of text terminated by a newline. 4 read-char & optional input-stream eof-error-p eof-value recursive-p It takes one character from input-stream and returns it as a character object. 5 unread-char character & optional input-stream It puts the character most recently read from the input-stream, onto the front of input-stream. 6 peek-char & optional peek-type input-stream eof-error-p eof-value recursive-p It returns the next character to be read from input-stream, without actually removing it from the input stream. 7 listen & optional input-stream The predicate listen is true if there is a character immediately available from input-stream, and is false if not. 8 read-char-no-hang & optional input-stream eof-error-p eof-value recursive-p It is similar to read-char, but if it does not get a character, it does not wait for a character, but returns nil immediately. 9 clear-input & optional input-stream It clears any buffered input associated with input-stream. 10 read-from-string string & optional eof-error-p eof-value & key :start :end :preserve-whitespace It takes the characters of the string successively and builds a LISP object and returns the object. It also returns the index of the first character in the string not read, or the length of the string (or, length +1), as the case may be. 11 parse-integer string & key :start :end :radix :junk-allowed It examines the substring of string delimited by :start and :end (default to the beginning and end of the string). It skips over whitespace characters and then attempts to parse an integer. 12 read-byte binary-input-stream & optional eof-error-p eof-value It reads one byte from the binary-input-stream and returns it in the form of an integer. Reading Input from Keyboard The read function is used for taking input from the keyboard. It may not take any argument. For example, consider the code snippet − (write ( + 15.0 (read))) Assume the user enters 10.2 from the STDIN Input, it returns, 25.2 The read function reads characters from an input stream and interprets them by parsing as representations of Lisp objects. Example Create a new source code file named main.lisp and type the following code in it − ; the function AreaOfCircle ; calculates area of a circle ; when the radius is input from keyboard (defun AreaOfCircle() (terpri) (princ “Enter Radius: “) (setq radius (read)) (setq area (* 3.1416 radius radius)) (princ “Area: “) (write area)) (AreaOfCircle) When you execute the code, it returns the following result − Enter Radius: 5 (STDIN Input) Area: 78.53999 Example Create a new source code file named main.lisp and type the following code in it. Live Demo (with-input-from-string (stream “Welcome to Tutorials Point!”) (print (read-char stream)) (print (read-char stream)) (print (read-char stream)) (print (read-char stream)) (print (read-char stream)) (print (read-char stream)) (print (read-char stream)) (print (read-char stream)) (print (read-char stream)) (print (read-char stream)) (print (peek-char nil stream nil ”the-end)) (values) ) When you execute the code, it returns the following result − #W #e #l #c #o #m #e #Space #t #o #Space The Output Functions All output functions in LISP take an optional argument called output-stream, where the output is sent. If not mentioned or nil, output-stream defaults to the value of the variable *standard-output*. The following table provides the most commonly used output functions of LISP − Sr.No. Function and Description 1 write object & key :stream :escape :radix :base :circle :pretty :level :length :case :gensym :array write object & key :stream :escape :radix :base :circle :pretty :level :length :case :gensym :array :readably :right-margin :miser-width :lines :pprint-dispatch Both write the object to the output stream specified by :stream, which defaults to the value of *standard-output*. Other values default to the corresponding global variables set for printing. 2 prin1 object & optional output-stream print object & optional output-stream pprint object & optional output-stream princ object & optional output-stream All these functions outputs the printed representation of object to output-stream. However, the following differences are there − prin1 returns the object as its value. print prints the object with a preceding newline and followed by a space. It returns object. pprint is just like print except that the trailing space is omitted. princ is just like prin1 except that the output has no escape character 3 write-to-string object & key :escape :radix :base :circle :pretty :level :length :case :gensym :array write-to-string object & key :escape :radix :base :circle :pretty :level :length :case :gensym :array :readably :right-margin :miser-width :lines :pprint-dispatch prin1-to-string object princ-to-string object The object is effectively printed and the output characters are made into a string, which is returned. 4 write-char character & optional output-stream It outputs the character to output-stream, and returns character. 5 write-string string & optional output-stream & key :start :end It writes the characters of the specified substring of string to the output-stream. 6 write-line string & optional output-stream & key :start :end It works the same way as write-string, but outputs a newline afterwards. 7 terpri & optional output-stream It outputs a newline to output-stream. 8 fresh-line & optional output-stream it outputs a newline only if the stream is not already at the start of a line. 9 finish-output & optional output-stream force-output & optional output-stream clear-output & optional output-stream The function finish-output attempts to ensure that all output sent to output-stream

LISP – Structures

LISP – Structures ”; Previous Next Structures are one of the user-defined data type, which allows you to combine data items of different kinds. Structures are used to represent a record. Suppose you want to keep track of your books in a library. You might want to track the following attributes about each book − Title Author Subject Book ID Defining a Structure The defstruct macro in LISP allows you to define an abstract record structure. The defstruct statement defines a new data type, with more than one member for your program. To discuss the format of the defstruct macro, let us write the definition of the Book structure. We could define the book structure as − (defstruct book title author subject book-id ) Please note The above declaration creates a book structure with four named components. So every book created will be an object of this structure. It defines four functions named book-title, book-author, book-subject and book-book-id, which will take one argument, a book structure, and will return the fields title, author, subject and book-id of the book object. These functions are called the access functions. The symbol book becomes a data type and you can check it using the typep predicate. There will also be an implicit function named book-p, which is a predicate and will be true if its argument is a book and is false otherwise. Another implicit function named make-book will be created, which is a constructor, which, when invoked, will create a data structure with four components, suitable for use with the access functions. The #S syntax refers to a structure, and you can use it to read or print instances of a book. An implicit function named copy-book of one argument is also defined that. It takes a book object and creates another book object, which is a copy of the first one. This function is called the copier function. You can use setf to alter the components of a book, for example (setf (book-book-id book3) 100) Example Create a new source code file named main.lisp and type the following code in it. Live Demo (defstruct book title author subject book-id ) ( setq book1 (make-book :title “C Programming” :author “Nuha Ali” :subject “C-Programming Tutorial” :book-id “478”) ) ( setq book2 (make-book :title “Telecom Billing” :author “Zara Ali” :subject “C-Programming Tutorial” :book-id “501”) ) (write book1) (terpri) (write book2) (setq book3( copy-book book1)) (setf (book-book-id book3) 100) (terpri) (write book3) When you execute the code, it returns the following result − #S(BOOK :TITLE “C Programming” :AUTHOR “Nuha Ali” :SUBJECT “C-Programming Tutorial” :BOOK-ID “478”) #S(BOOK :TITLE “Telecom Billing” :AUTHOR “Zara Ali” :SUBJECT “C-Programming Tutorial” :BOOK-ID “501”) #S(BOOK :TITLE “C Programming” :AUTHOR “Nuha Ali” :SUBJECT “C-Programming Tutorial” :BOOK-ID 100) Print Page Previous Next Advertisements ”;

LISP – Predicates

LISP – Predicates ”; Previous Next Predicates are functions that test their arguments for some specific conditions and returns nil if the condition is false, or some non-nil value is the condition is true. The following table shows some of the most commonly used predicates − Sr.No. Predicate & Description 1 atom It takes one argument and returns t if the argument is an atom or nil if otherwise. 2 equal It takes two arguments and returns t if they are structurally equal or nil otherwise. 3 eq It takes two arguments and returns t if they are same identical objects, sharing the same memory location or nil otherwise. 4 eql It takes two arguments and returns t if the arguments are eq, or if they are numbers of the same type with the same value, or if they are character objects that represent the same character, or nil otherwise. 5 evenp It takes one numeric argument and returns t if the argument is even number or nil if otherwise. 6 oddp It takes one numeric argument and returns t if the argument is odd number or nil if otherwise. 7 zerop It takes one numeric argument and returns t if the argument is zero or nil if otherwise. 8 null It takes one argument and returns t if the argument evaluates to nil, otherwise it returns nil. 9 listp It takes one argument and returns t if the argument evaluates to a list otherwise it returns nil. 10 greaterp It takes one or more argument and returns t if either there is a single argument or the arguments are successively larger from left to right, or nil if otherwise. 11 lessp It takes one or more argument and returns t if either there is a single argument or the arguments are successively smaller from left to right, or nil if otherwise. 12 numberp It takes one argument and returns t if the argument is a number or nil if otherwise. 13 symbolp It takes one argument and returns t if the argument is a symbol otherwise it returns nil. 14 integerp It takes one argument and returns t if the argument is an integer otherwise it returns nil. 15 rationalp It takes one argument and returns t if the argument is rational number, either a ratio or a number, otherwise it returns nil. 16 floatp It takes one argument and returns t if the argument is a floating point number otherwise it returns nil. 17 realp It takes one argument and returns t if the argument is a real number otherwise it returns nil. 18 complexp It takes one argument and returns t if the argument is a complex number otherwise it returns nil. 19 characterp It takes one argument and returns t if the argument is a character otherwise it returns nil. 20 stringp It takes one argument and returns t if the argument is a string object otherwise it returns nil. 21 arrayp It takes one argument and returns t if the argument is an array object otherwise it returns nil. 22 packagep It takes one argument and returns t if the argument is a package otherwise it returns nil. Example 1 Create a new source code file named main.lisp and type the following code in it. Live Demo (write (atom ”abcd)) (terpri) (write (equal ”a ”b)) (terpri) (write (evenp 10)) (terpri) (write (evenp 7 )) (terpri) (write (oddp 7 )) (terpri) (write (zerop 0.0000000001)) (terpri) (write (eq 3 3.0 )) (terpri) (write (equal 3 3.0 )) (terpri) (write (null nil )) When you execute the code, it returns the following result − T NIL T NIL T NIL NIL NIL T Example 2 Create a new source code file named main.lisp and type the following code in it. Live Demo (defun factorial (num) (cond ((zerop num) 1) (t ( * num (factorial (- num 1)))) ) ) (setq n 6) (format t “~% Factorial ~d is: ~d” n (factorial n)) When you execute the code, it returns the following result − Factorial 6 is: 720 Print Page Previous Next Advertisements ”;

LISP – Numbers

LISP – Numbers ”; Previous Next Common Lisp defines several kinds of numbers. The number data type includes various kinds of numbers supported by LISP. The number types supported by LISP are − Integers Ratios Floating-point numbers Complex numbers The following diagram shows the number hierarchy and various numeric data types available in LISP − Various Numeric Types in LISP The following table describes various number type data available in LISP − Sr.No. Data type & Description 1 fixnum This data type represents integers which are not too large and mostly in the range -215 to 215-1 (it is machine-dependent) 2 bignum These are very large numbers with size limited by the amount of memory allocated for LISP, they are not fixnum numbers. 3 ratio Represents the ratio of two numbers in the numerator/denominator form. The / function always produce the result in ratios, when its arguments are integers. 4 float It represents non-integer numbers. There are four float data types with increasing precision. 5 complex It represents complex numbers, which are denoted by #c. The real and imaginary parts could be both either rational or floating point numbers. Example Create a new source code file named main.lisp and type the following code in it. Live Demo (write (/ 1 2)) (terpri) (write ( + (/ 1 2) (/ 3 4))) (terpri) (write ( + #c( 1 2) #c( 3 -4))) When you execute the code, it returns the following result − 1/2 5/4 #C(4 -2) Number Functions The following table describes some commonly used numeric functions − Sr.No. Function & Description 1 +, -, *, / Respective arithmetic operations 2 sin, cos, tan, acos, asin, atan Respective trigonometric functions. 3 sinh, cosh, tanh, acosh, asinh, atanh Respective hyperbolic functions. 4 exp Exponentiation function. Calculates ex 5 expt Exponentiation function, takes base and power both. 6 sqrt It calculates the square root of a number. 7 log Logarithmic function. It one parameter is given, then it calculates its natural logarithm, otherwise the second parameter is used as base. 8 conjugate It calculates the complex conjugate of a number. In case of a real number, it returns the number itself. 9 abs It returns the absolute value (or magnitude) of a number. 10 gcd It calculates the greatest common divisor of the given numbers. 11 lcm It calculates the least common multiple of the given numbers. 12 isqrt It gives the greatest integer less than or equal to the exact square root of a given natural number. 13 floor, ceiling, truncate, round All these functions take two arguments as a number and returns the quotient; floor returns the largest integer that is not greater than ratio, ceiling chooses the smaller integer that is larger than ratio, truncate chooses the integer of the same sign as ratio with the largest absolute value that is less than absolute value of ratio, and round chooses an integer that is closest to ratio. 14 ffloor, fceiling, ftruncate, fround Does the same as above, but returns the quotient as a floating point number. 15 mod, rem Returns the remainder in a division operation. 16 float Converts a real number to a floating point number. 17 rational, rationalize Converts a real number to rational number. 18 numerator, denominator Returns the respective parts of a rational number. 19 realpart, imagpart Returns the real and imaginary part of a complex number. Example Create a new source code file named main.lisp and type the following code in it. Live Demo (write (/ 45 78)) (terpri) (write (floor 45 78)) (terpri) (write (/ 3456 75)) (terpri) (write (floor 3456 75)) (terpri) (write (ceiling 3456 75)) (terpri) (write (truncate 3456 75)) (terpri) (write (round 3456 75)) (terpri) (write (ffloor 3456 75)) (terpri) (write (fceiling 3456 75)) (terpri) (write (ftruncate 3456 75)) (terpri) (write (fround 3456 75)) (terpri) (write (mod 3456 75)) (terpri) (setq c (complex 6 7)) (write c) (terpri) (write (complex 5 -9)) (terpri) (write (realpart c)) (terpri) (write (imagpart c)) When you execute the code, it returns the following result − 15/26 0 1152/25 46 47 46 46 46.0 47.0 46.0 46.0 6 #C(6 7) #C(5 -9) 6 7 Print Page Previous Next Advertisements ”;

Lisp – Useful Resources

LISP – Useful Resources ”; Previous Next The following resources contain additional information on LISP. Please use them to get more in-depth knowledge on this topic. CCNP CCIE Enterprise: ENCOR 350-401 Training Part-2/2 74 Lectures 27.5 hours Ahmad Ali More Detail Complete Teaching of ENCOR 350-401 by Arash Deljoo 137 Lectures 139.5 hours Arash Deljoo More Detail Comprehensive Plumbing Design Course (Calculations, CAD and Revit) 97 Lectures 21 hours Ahmed Sami More Detail Print Page Previous Next Advertisements ”;

LISP – Error Handling

LISP – Error Handling ”; Previous Next In Common LISP terminology, exceptions are called conditions. In fact, conditions are more general than exceptions in traditional programming languages, because a condition represents any occurrence, error, or not, which might affect various levels of function call stack. Condition handling mechanism in LISP, handles such situations in such a way that conditions are used to signal warning (say by printing an warning) while the upper level code on the call stack can continue its work. The condition handling system in LISP has three parts − Signalling a condition Handling the condition Restart the process Handling a Condition Let us take up an example of handling a condition arising out of divide by zero condition, to explain the concepts here. You need to take the following steps for handling a condition − Define the Condition − “A condition is an object whose class indicates the general nature of the condition and whose instance data carries information about the details of the particular circumstances that lead to the condition being signalled”. The define-condition macro is used for defining a condition, which has the following syntax − (define-condition condition-name (error) ((text :initarg :text :reader text)) ) New condition objects are created with MAKE-CONDITION macro, which initializes the slots of the new condition based on the :initargs argument. In our example, the following code defines the condition − (define-condition on-division-by-zero (error) ((message :initarg :message :reader message)) ) Writing the Handlers − a condition handler is a code that are used for handling the condition signalled thereon. It is generally written in one of the higher level functions that call the erroring function. When a condition is signalled, the signalling mechanism searches for an appropriate handler based on the condition”s class. Each handler consists of − Type specifier, that indicates the type of condition it can handle A function that takes a single argument, the condition When a condition is signalled, the signalling mechanism finds the most recently established handler that is compatible with the condition type and calls its function. The macro handler-case establishes a condition handler. The basic form of a handler-case − (handler-case expression error-clause*) Where, each error clause is of the form − condition-type ([var]) code) Restarting Phase This is the code that actually recovers your program from errors, and condition handlers can then handle a condition by invoking an appropriate restart. The restart code is generally place in middle-level or low-level functions and the condition handlers are placed into the upper levels of the application. The handler-bind macro allows you to provide a restart function, and allows you to continue at the lower level functions without unwinding the function call stack. In other words, the flow of control will still be in the lower level function. The basic form of handler-bind is as follows − (handler-bind (binding*) form*) Where each binding is a list of the following − a condition type a handler function of one argument The invoke-restart macro finds and invokes the most recently bound restart function with the specified name as argument. You can have multiple restarts. Example In this example, we demonstrate the above concepts by writing a function named division-function, which will create an error condition if the divisor argument is zero. We have three anonymous functions that provide three ways to come out of it – by returning a value 1, by sending a divisor 2 and recalculating, or by returning 1. Create a new source code file named main.lisp and type the following code in it. Live Demo (define-condition on-division-by-zero (error) ((message :initarg :message :reader message)) ) (defun handle-infinity () (restart-case (let ((result 0)) (setf result (division-function 10 0)) (format t “Value: ~a~%” result) ) (just-continue () nil) ) ) (defun division-function (value1 value2) (restart-case (if (/= value2 0) (/ value1 value2) (error ”on-division-by-zero :message “denominator is zero”) ) (return-zero () 0) (return-value (r) r) (recalc-using (d) (division-function value1 d)) ) ) (defun high-level-code () (handler-bind ( (on-division-by-zero #”(lambda (c) (format t “error signaled: ~a~%” (message c)) (invoke-restart ”return-zero) ) ) (handle-infinity) ) ) ) (handler-bind ( (on-division-by-zero #”(lambda (c) (format t “error signaled: ~a~%” (message c)) (invoke-restart ”return-value 1) ) ) ) (handle-infinity) ) (handler-bind ( (on-division-by-zero #”(lambda (c) (format t “error signaled: ~a~%” (message c)) (invoke-restart ”recalc-using 2) ) ) ) (handle-infinity) ) (handler-bind ( (on-division-by-zero #”(lambda (c) (format t “error signaled: ~a~%” (message c)) (invoke-restart ”just-continue) ) ) ) (handle-infinity) ) (format t “Done.”)) When you execute the code, it returns the following result − error signaled: denominator is zero Value: 1 error signaled: denominator is zero Value: 5 error signaled: denominator is zero Done. Apart from the ”Condition System”, as discussed above, Common LISP also provides various functions that may be called for signalling an error. Handling of an error, when signalled, is however, implementation-dependent. Error Signalling Functions in LISP The following table provides commonly used functions signalling warnings, breaks, non-fatal and fatal errors. The user program specifies an error message (a string). The functions process this message and may/may not display it to the user. The error messages should be constructed by applying the format function, should not contain a newline character at either the beginning or end, and need not indicate error, as the LISP system will take care of these according to its preferred style. Sr.No. Function and Description 1 error format-string &rest args It signals a fatal error. It is impossible to continue from this kind of error; thus error will never return to its caller. 2 cerror continue-format-string error-format-string &rest args It signals an error and enters the debugger. However, it allows the program to be continued from the debugger after resolving the error. 3 warn format-string &rest args it prints an error message but normally doesn”t go into the debugger 4 break &optional format-string &rest args It prints the message and goes directly into the debugger, without allowing any possibility of interception by programmed error-handling facilities Example In this example, the factorial

LISP – Characters

LISP – Characters ”; Previous Next In LISP, characters are represented as data objects of type character. You can denote a character object preceding # before the character itself. For example, #a means the character a. Space and other special characters can be denoted by preceding # before the name of the character. For example, #SPACE represents the space character. The following example demonstrates this − Example Create a new source code file named main.lisp and type the following code in it. Live Demo (write ”a) (terpri) (write #a) (terpri) (write-char #a) (terpri) (write-char ”a) When you execute the code, it returns the following result − A #a a *** – WRITE-CHAR: argument A is not a character Special Characters Common LISP allows using the following special characters in your code. They are called the semi-standard characters. #Backspace #Tab #Linefeed #Page #Return #Rubout Character Comparison Functions Numeric comparison functions and operators, like, < and > do not work on characters. Common LISP provides other two sets of functions for comparing characters in your code. One set is case-sensitive and the other case-insensitive. The following table provides the functions − Case Sensitive Functions Case-insensitive Functions Description char= char-equal Checks if the values of the operands are all equal or not, if yes then condition becomes true. char/= char-not-equal Checks if the values of the operands are all different or not, if values are not equal then condition becomes true. char< char-lessp Checks if the values of the operands are monotonically decreasing. char> char-greaterp Checks if the values of the operands are monotonically increasing. char<= char-not-greaterp Checks if the value of any left operand is greater than or equal to the value of next right operand, if yes then condition becomes true. char>= char-not-lessp Checks if the value of any left operand is less than or equal to the value of its right operand, if yes then condition becomes true. Example Create a new source code file named main.lisp and type the following code in it. Live Demo ; case-sensitive comparison (write (char= #a #b)) (terpri) (write (char= #a #a)) (terpri) (write (char= #a #A)) (terpri) ;case-insensitive comparision (write (char-equal #a #A)) (terpri) (write (char-equal #a #b)) (terpri) (write (char-lessp #a #b #c)) (terpri) (write (char-greaterp #a #b #c)) When you execute the code, it returns the following result − NIL T NIL T NIL T NIL Print Page Previous Next Advertisements ”;

Lisp – Quick Guide

LISP – Quick Guide ”; Previous Next LISP – Overview John McCarthy invented LISP in 1958, shortly after the development of FORTRAN. It was first implemented by Steve Russell on an IBM 704 computer. It is particularly suitable for Artificial Intelligence programs, as it processes symbolic information effectively. Common Lisp originated, during the 1980s and 1990s, in an attempt to unify the work of several implementation groups that were successors to Maclisp, like ZetaLisp and NIL (New Implementation of Lisp) etc. It serves as a common language, which can be easily extended for specific implementation. Programs written in Common LISP do not depend on machine-specific characteristics, such as word length etc. Features of Common LISP It is machine-independent It uses iterative design methodology, and easy extensibility. It allows updating the programs dynamically. It provides high level debugging. It provides advanced object-oriented programming. It provides a convenient macro system. It provides wide-ranging data types like, objects, structures, lists, vectors, adjustable arrays, hash-tables, and symbols. It is expression-based. It provides an object-oriented condition system. It provides a complete I/O library. It provides extensive control structures. Applications Built in LISP Large successful applications built in Lisp. Emacs G2 AutoCad Igor Engraver Yahoo Store LISP – Environment Setup Local Environment Setup If you are still willing to set up your environment for Lisp programming language, you need the following two softwares available on your computer, (a) Text Editor and (b) The Lisp Executer. Text Editor This will be used to type your program. Examples of few editors include Windows Notepad, OS Edit command, Brief, Epsilon, EMACS, and vim or vi. Name and version of text editor can vary on different operating systems. For example, Notepad will be used on Windows, and vim or vi can be used on windows as well as Linux or UNIX. The files you create with your editor are called source files and contain program source code. The source files for Lisp programs are typically named with the extension “.lisp“. Before starting your programming, make sure you have one text editor in place and you have enough experience to write a computer program, save it in a file, finally execute it. The Lisp Executer The source code written in source file is the human readable source for your program. It needs to be “executed”, to turn into machine language so that your CPU can actually execute the program as per instructions given. This Lisp programming language will be used to execute your source code into final executable program. I assume you have basic knowledge about a programming language. CLISP is the GNU Common LISP multi-architechtural compiler used for setting up LISP in Windows. The windows version emulates a unix environment using MingW under windows. The installer takes care of this and automatically adds clisp to the windows PATH variable. You can get the latest CLISP for Windows from here – https://sourceforge.net/projects/clisp/files/latest/download It creates a shortcut in the Start Menu by default, for the line-by-line interpreter. How to use CLISP During installation, clisp is automatically added to your PATH variable if you select the option (RECOMMENDED) This means that you can simply open a new Command Prompt window and type “clisp” to bring up the compiler. To run a *.lisp or *.lsp file, simply use − clisp hello.lisp LISP – Program Structure LISP expressions are called symbolic expressions or s-expressions. The s-expressions are composed of three valid objects, atoms, lists and strings. Any s-expression is a valid program. LISP programs run either on an interpreter or as compiled code. The interpreter checks the source code in a repeated loop, which is also called the read-evaluate-print loop (REPL). It reads the program code, evaluates it, and prints the values returned by the program. A Simple Program Let us write an s-expression to find the sum of three numbers 7, 9 and 11. To do this, we can type at the interpreter prompt. (+ 7 9 11) LISP returns the result − 27 If you would like to run the same program as a compiled code, then create a LISP source code file named myprog.lisp and type the following code in it. Live Demo (write (+ 7 9 11)) When you click the Execute button, or type Ctrl+E, LISP executes it immediately and the result returned is − 27 LISP Uses Prefix Notation You might have noted that LISP uses prefix notation. In the above program the + symbol works as the function name for the process of summation of the numbers. In prefix notation, operators are written before their operands. For example, the expression, a * ( b + c ) / d will be written as − (/ (* a (+ b c) ) d) Let us take another example, let us write code for converting Fahrenheit temp of 60o F to the centigrade scale − The mathematical expression for this conversion will be − (60 * 9 / 5) + 32 Create a source code file named main.lisp and type the following code in it. Live Demo (write(+ (* (/ 9 5) 60) 32)) When you click the Execute button, or type Ctrl+E, LISP executes it immediately and the result returned is− 140 Evaluation of LISP Programs Evaluation of LISP programs has two parts − Translation of program text into Lisp objects by a reader program Implementation of the semantics of the language in terms of these objects by an evaluator program The evaluation process takes the following steps − The reader translates the strings of characters to LISP objects or s-expressions. The evaluator defines syntax of Lisp forms that are built from s-expressions. This second level of evaluation defines a syntax that determines which s-expressions are LISP forms. The evaluator works as a function that takes a valid LISP form as an argument and returns a value. This is the reason why we put the LISP expression in parenthesis, because we are sending the entire expression/form to the evaluator as arguments. The ”Hello World” Program

LISP – Symbols

LISP – Symbols ”; Previous Next In LISP, a symbol is a name that represents data objects and interestingly it is also a data object. What makes symbols special is that they have a component called the property list, or plist. Property Lists LISP allows you to assign properties to symbols. For example, let us have a ”person” object. We would like this ”person” object to have properties like name, sex, height, weight, address, profession etc. A property is like an attribute name. A property list is implemented as a list with an even number (possibly zero) of elements. Each pair of elements in the list constitutes an entry; the first item is the indicator, and the second is the value. When a symbol is created, its property list is initially empty. Properties are created by using get within a setf form. For example, the following statements allow us to assign properties title, author and publisher, and respective values, to an object named (symbol) ”book”. Example 1 Create a new source code file named main.lisp and type the following code in it. Live Demo (write (setf (get ”books”title) ”(Gone with the Wind))) (terpri) (write (setf (get ”books ”author) ”(Margaret Michel))) (terpri) (write (setf (get ”books ”publisher) ”(Warner Books))) When you execute the code, it returns the following result − (GONE WITH THE WIND) (MARGARET MICHEL) (WARNER BOOKS) Various property list functions allow you to assign properties as well as retrieve, replace or remove the properties of a symbol. The get function returns the property list of symbol for a given indicator. It has the following syntax − get symbol indicator &optional default The get function looks for the property list of the given symbol for the specified indicator, if found then it returns the corresponding value; otherwise default is returned (or nil, if a default value is not specified). Example 2 Create a new source code file named main.lisp and type the following code in it. Live Demo (setf (get ”books ”title) ”(Gone with the Wind)) (setf (get ”books ”author) ”(Margaret Micheal)) (setf (get ”books ”publisher) ”(Warner Books)) (write (get ”books ”title)) (terpri) (write (get ”books ”author)) (terpri) (write (get ”books ”publisher)) When you execute the code, it returns the following result − (GONE WITH THE WIND) (MARGARET MICHEAL) (WARNER BOOKS) The symbol-plist function allows you to see all the properties of a symbol. Example 3 Create a new source code file named main.lisp and type the following code in it. Live Demo (setf (get ”annie ”age) 43) (setf (get ”annie ”job) ”accountant) (setf (get ”annie ”sex) ”female) (setf (get ”annie ”children) 3) (terpri) (write (symbol-plist ”annie)) When you execute the code, it returns the following result − (CHILDREN 3 SEX FEMALE JOB ACCOUNTANT AGE 43) The remprop function removes the specified property from a symbol. Example 4 Create a new source code file named main.lisp and type the following code in it. Live Demo (setf (get ”annie ”age) 43) (setf (get ”annie ”job) ”accountant) (setf (get ”annie ”sex) ”female) (setf (get ”annie ”children) 3) (terpri) (write (symbol-plist ”annie)) (remprop ”annie ”age) (terpri) (write (symbol-plist ”annie)) When you execute the code, it returns the following result − (CHILDREN 3 SEX FEMALE JOB ACCOUNTANT AGE 43) (CHILDREN 3 SEX FEMALE JOB ACCOUNTANT) Print Page Previous Next Advertisements ”;

LISP – Arrays

LISP – Arrays ”; Previous Next LISP allows you to define single or multiple-dimension arrays using the make-array function. An array can store any LISP object as its elements. All arrays consist of contiguous memory locations. The lowest address corresponds to the first element and the highest address to the last element. The number of dimensions of an array is called its rank. In LISP, an array element is specified by a sequence of non-negative integer indices. The length of the sequence must equal the rank of the array. Indexing starts from zero. For example, to create an array with 10- cells, named my-array, we can write − (setf my-array (make-array ”(10))) The aref function allows accessing the contents of the cells. It takes two arguments, the name of the array and the index value. For example, to access the content of the tenth cell, we write − (aref my-array 9) Example 1 Create a new source code file named main.lisp and type the following code in it. Live Demo (write (setf my-array (make-array ”(10)))) (terpri) (setf (aref my-array 0) 25) (setf (aref my-array 1) 23) (setf (aref my-array 2) 45) (setf (aref my-array 3) 10) (setf (aref my-array 4) 20) (setf (aref my-array 5) 17) (setf (aref my-array 6) 25) (setf (aref my-array 7) 19) (setf (aref my-array 8) 67) (setf (aref my-array 9) 30) (write my-array) When you execute the code, it returns the following result − #(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL) #(25 23 45 10 20 17 25 19 67 30) Example 2 Let us create a 3-by-3 array. Create a new source code file named main.lisp and type the following code in it. Live Demo (setf x (make-array ”(3 3) :initial-contents ”((0 1 2 ) (3 4 5) (6 7 8))) ) (write x) When you execute the code, it returns the following result − #2A((0 1 2) (3 4 5) (6 7 8)) Example 3 Create a new source code file named main.lisp and type the following code in it. Live Demo (setq a (make-array ”(4 3))) (dotimes (i 4) (dotimes (j 3) (setf (aref a i j) (list i ”x j ”= (* i j))) ) ) (dotimes (i 4) (dotimes (j 3) (print (aref a i j)) ) ) When you execute the code, it returns the following result − (0 X 0 = 0) (0 X 1 = 0) (0 X 2 = 0) (1 X 0 = 0) (1 X 1 = 1) (1 X 2 = 2) (2 X 0 = 0) (2 X 1 = 2) (2 X 2 = 4) (3 X 0 = 0) (3 X 1 = 3) (3 X 2 = 6) Complete Syntax for the make-array Function The make-array function takes many other arguments. Let us look at the complete syntax of this function − make-array dimensions :element-type :initial-element :initial-contents :adjustable :fill-pointer :displaced-to :displaced-index-offset Apart from the dimensions argument, all other arguments are keywords. The following table provides brief description of the arguments. Sr.No. Argument & Description 1 dimensions It gives the dimensions of the array. It is a number for one-dimensional array, and a list for multi-dimensional array. 2 :element-type It is the type specifier, default value is T, i.e. any type 3 :initial-element Initial elements value. It will make an array with all the elements initialized to a particular value. 4 :initial-content Initial content as object. 5 :adjustable It helps in creating a resizeable (or adjustable) vector whose underlying memory can be resized. The argument is a Boolean value indicating whether the array is adjustable or not, default value being NIL. 6 :fill-pointer It keeps track of the number of elements actually stored in a resizeable vector. 7 :displaced-to It helps in creating a displaced array or shared array that shares its contents with the specified array. Both the arrays should have same element type. The :displaced-to option may not be used with the :initial-element or :initial-contents option. This argument defaults to nil. 8 :displaced-index-offset It gives the index-offset of the created shared array. Example 4 Create a new source code file named main.lisp and type the following code in it. Live Demo (setq myarray (make-array ”(3 2 3) :initial-contents ”(((a b c) (1 2 3)) ((d e f) (4 5 6)) ((g h i) (7 8 9)) )) ) (setq array2 (make-array 4 :displaced-to myarray :displaced-index-offset 2)) (write myarray) (terpri) (write array2) When you execute the code, it returns the following result − #3A(((A B C) (1 2 3)) ((D E F) (4 5 6)) ((G H I) (7 8 9))) #(C 1 2 3) If the displaced array is two dimensional − Live Demo (setq myarray (make-array ”(3 2 3) :initial-contents ”(((a b c) (1 2 3)) ((d e f) (4 5 6)) ((g h i) (7 8 9)) )) ) (setq array2 (make-array ”(3 2) :displaced-to myarray :displaced-index-offset 2)) (write myarray) (terpri) (write array2) When you execute the code, it returns the following result − #3A(((A B C) (1 2 3)) ((D E F) (4 5 6)) ((G H I) (7 8 9))) #2A((C 1) (2 3) (D E)) Let”s change the displaced index offset to 5 − Live Demo (setq myarray (make-array ”(3 2 3) :initial-contents ”(((a b c) (1 2 3)) ((d e f) (4 5 6)) ((g h i) (7 8 9)) )) ) (setq array2 (make-array ”(3 2) :displaced-to myarray :displaced-index-offset 5)) (write myarray) (terpri) (write array2) When you execute the code, it returns the following result − #3A(((A B C) (1 2 3)) ((D E F) (4 5 6)) ((G H I) (7 8 9))) #2A((3 D) (E F) (4 5)) Example 5 Create a new source code file named main.lisp and type the following code in it. Live Demo ;a one dimensional array with 5 elements, ;initail value 5 (write (make-array 5 :initial-element 5)) (terpri) ;two dimensional array, with initial element a (write (make-array ”(2 3) :initial-element ”a)) (terpri) ;an array of capacity 14,