Lisp – Discussion

Discuss LISP ”; Previous Next Lisp is the second-oldest high-level programming language after Fortran and has changed a great deal since its early days, and a number of dialects have existed over its history. Today, the most widely known general-purpose Lisp dialects are Common Lisp and Scheme. Lisp was invented by John McCarthy in 1958 while he was at the Massachusetts Institute of Technology (MIT). This reference will take you through simple and practical approach while learning LISP Programming language. Print Page Previous Next Advertisements ”;

LISP – Packages

LISP – Packages ”; Previous Next In general term of programming languages, a package is designed for providing a way to keep one set of names separate from another. The symbols declared in one package will not conflict with the same symbols declared in another. This way packages reduce the naming conflicts between independent code modules. The LISP reader maintains a table of all the symbols it has found. When it finds a new character sequence, it creates a new symbol and stores in the symbol table. This table is called a package. The current package is referred by the special variable *package*. There are two predefined packages in LISP − common-lisp − it contains symbols for all the functions and variables defined. common-lisp-user − it uses the common-lisp package and all other packages with editing and debugging tools; it is called cl-user in short Package Functions in LISP The following table provides most commonly used functions used for creating, using and manipulating packages − Sr.No. Function and Description 1 make-package package-name &key :nicknames :use It creates and returns a new package with the specified package name. 2 in-package package-name &key :nicknames :use Makes the package current. 3 in-package name This macro causes *package* to be set to the package named name, which must be a symbol or string. 4 find-package name It searches for a package. The package with that name or nickname is returned; if no such package exists, find-package returns nil. 5 rename-package package new-name &optional new-nicknames it renames a package. 6 list-all-packages This function returns a list of all packages that currently exist in the Lisp system. 7 delete-package package It deletes a package. Creating a LISP Package The defpackage function is used for creating an user defined package. It has the following syntax − (defpackage :package-name (:use :common-lisp …) (:export :symbol1 :symbol2 …) ) Where, package-name is the name of the package. The :use keyword specifies the packages that this package needs, i.e., packages that define functions used by code in this package. The :export keyword specifies the symbols that are external in this package. The make-package function is also used for creating a package. The syntax for this function is − make-package package-name &key :nicknames :use The arguments and keywords has same meaning as before. Using a Package Once you have created a package, you can use the code in this package, by making it the current package. The in-package macro makes a package current in the environment. Example Create a new source code file named main.lisp and type the following code in it. Live Demo (make-package :tom) (make-package :dick) (make-package :harry) (in-package tom) (defun hello () (write-line “Hello! This is Tom”s Tutorials Point”) ) (hello) (in-package dick) (defun hello () (write-line “Hello! This is Dick”s Tutorials Point”) ) (hello) (in-package harry) (defun hello () (write-line “Hello! This is Harry”s Tutorials Point”) ) (hello) (in-package tom) (hello) (in-package dick) (hello) (in-package harry) (hello) When you execute the code, it returns the following result − Hello! This is Tom”s Tutorials Point Hello! This is Dick”s Tutorials Point Hello! This is Harry”s Tutorials Point Deleting a Package The delete-package macro allows you to delete a package. The following example demonstrates this − Example Create a new source code file named main.lisp and type the following code in it. Live Demo (make-package :tom) (make-package :dick) (make-package :harry) (in-package tom) (defun hello () (write-line “Hello! This is Tom”s Tutorials Point”) ) (in-package dick) (defun hello () (write-line “Hello! This is Dick”s Tutorials Point”) ) (in-package harry) (defun hello () (write-line “Hello! This is Harry”s Tutorials Point”) ) (in-package tom) (hello) (in-package dick) (hello) (in-package harry) (hello) (delete-package tom) (in-package tom) (hello) When you execute the code, it returns the following result − Hello! This is Tom”s Tutorials Point Hello! This is Dick”s Tutorials Point Hello! This is Harry”s Tutorials Point *** – EVAL: variable TOM has no value Print Page Previous Next Advertisements ”;

LISP – Strings

LISP – Strings ”; Previous Next Strings in Common Lisp are vectors, i.e., one-dimensional array of characters. String literals are enclosed in double quotes. Any character supported by the character set can be enclosed within double quotes to make a string, except the double quote character (“) and the escape character (). However, you can include these by escaping them with a backslash (). Example Create a new source code file named main.lisp and type the following code in it. Live Demo (write-line “Hello World”) (write-line “Welcome to Tutorials Point”) ;escaping the double quote character (write-line “Welcome to “Tutorials Point””) When you execute the code, it returns the following result − Hello World Welcome to Tutorials Point Welcome to “Tutorials Point” String Comparison Functions Numeric comparison functions and operators, like, < and > do not work on strings. Common LISP provides other two sets of functions for comparing strings 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 string= string-equal Checks if the values of the operands are all equal or not, if yes then condition becomes true. string/= string-not-equal Checks if the values of the operands are all different or not, if values are not equal then condition becomes true. string< string-lessp Checks if the values of the operands are monotonically decreasing. string> string-greaterp Checks if the values of the operands are monotonically increasing. string<= string-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. string>= string-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 (string= “this is test” “This is test”)) (terpri) (write (string> “this is test” “This is test”)) (terpri) (write (string< “this is test” “This is test”)) (terpri) ;case-insensitive comparision (write (string-equal “this is test” “This is test”)) (terpri) (write (string-greaterp “this is test” “This is test”)) (terpri) (write (string-lessp “this is test” “This is test”)) (terpri) ;checking non-equal (write (string/= “this is test” “this is Test”)) (terpri) (write (string-not-equal “this is test” “This is test”)) (terpri) (write (string/= “lisp” “lisping”)) (terpri) (write (string/= “decent” “decency”)) When you execute the code, it returns the following result − NIL 0 NIL T NIL NIL 8 NIL 4 5 Case Controlling Functions The following table describes the case controlling functions − Sr.No. Function & Description 1 string-upcase Converts the string to upper case 2 string-downcase Converts the string to lower case 3 string-capitalize Capitalizes each word in the string Example Create a new source code file named main.lisp and type the following code in it. Live Demo (write-line (string-upcase “a big hello from tutorials point”)) (write-line (string-capitalize “a big hello from tutorials point”)) When you execute the code, it returns the following result − A BIG HELLO FROM TUTORIALS POINT A Big Hello From Tutorials Point Trimming Strings The following table describes the string trimming functions − Sr.No. Function & Description 1 string-trim It takes a string of character(s) as first argument and a string as the second argument and returns a substring where all characters that are in the first argument are removed off the argument string. 2 String-left-trim It takes a string of character(s) as first argument and a string as the second argument and returns a substring where all characters that are in the first argument are removed off the beginning of the argument string. 3 String-right-trim It takes a string character(s) as first argument and a string as the second argument and returns a substring where all characters that are in the first argument are removed off the end of the argument string. Example Create a new source code file named main.lisp and type the following code in it. Live Demo (write-line (string-trim ” ” ” a big hello from tutorials point “)) (write-line (string-left-trim ” ” ” a big hello from tutorials point “)) (write-line (string-right-trim ” ” ” a big hello from tutorials point “)) (write-line (string-trim ” a” ” a big hello from tutorials point “)) When you execute the code, it returns the following result − a big hello from tutorials point a big hello from tutorials point a big hello from tutorials point big hello from tutorials point Other String Functions Strings in LISP are arrays and thus also sequences. We will cover these data types in coming tutorials. All functions that are applicable to arrays and sequences also apply to strings. However, we will demonstrate some commonly used functions using various examples. Calculating Length The length function calculates the length of a string. Extracting Sub-string The subseq function returns a sub-string (as a string is also a sequence) starting at a particular index and continuing to a particular ending index or the end of the string. Accessing a Character in a String The char function allows accessing individual characters of a string. Example Create a new source code file named main.lisp and type the following code in it. Live Demo (write (length “Hello World”)) (terpri) (write-line (subseq “Hello World” 6)) (write (char “Hello World” 6)) When you execute the code, it returns the following result − 11 World #W Sorting and Merging of Strings The sort function allows sorting a string. It takes a sequence (vector or string) and a two-argument predicate and returns a sorted version of the sequence. The merge function takes two sequences and a predicate and returns a sequence produced by merging the two sequences, according to the predicate. Example Create a new source code file named main.lisp and type the following code in it. Live Demo ;sorting the strings (write (sort (vector “Amal” “Akbar” “Anthony”) #”string<)) (terpri) ;merging the strings (write (merge ”vector (vector “Rishi” “Zara” “Priyanka”)

LISP – CLOS

LISP – CLOS ”; Previous Next Common LISP predated the advance of object-oriented programming by couple of decades. However, it object-orientation was incorporated into it at a later stage. Defining Classes The defclass macro allows creating user-defined classes. It establishes a class as a data type. It has the following syntax − (defclass class-name (superclass-name*) (slot-description*) class-option*)) The slots are variables that store data, or fields. A slot-description has the form (slot-name slot-option*), where each option is a keyword followed by a name, expression and other options. Most commonly used slot options are − :accessor function-name :initform expression :initarg symbol For example, let us define a Box class, with three slots length, breadth, and height. (defclass Box () (length breadth height) ) Providing Access and Read/Write Control to a Slot Unless the slots have values that can be accessed, read or written to, classes are pretty useless. You can specify accessors for each slot when you define a class. For example, take our Box class − (defclass Box () ((length :accessor length) (breadth :accessor breadth) (height :accessor height) ) ) You can also specify separate accessor names for reading and writing a slot. (defclass Box () ((length :reader get-length :writer set-length) (breadth :reader get-breadth :writer set-breadth) (height :reader get-height :writer set-height) ) ) Creating Instance of a Class The generic function make-instance creates and returns a new instance of a class. It has the following syntax − (make-instance class {initarg value}*) Example Let us create a Box class, with three slots, length, breadth and height. We will use three slot accessors to set the values in these fields. Create a new source code file named main.lisp and type the following code in it. Live Demo (defclass box () ((length :accessor box-length) (breadth :accessor box-breadth) (height :accessor box-height) ) ) (setf item (make-instance ”box)) (setf (box-length item) 10) (setf (box-breadth item) 10) (setf (box-height item) 5) (format t “Length of the Box is ~d~%” (box-length item)) (format t “Breadth of the Box is ~d~%” (box-breadth item)) (format t “Height of the Box is ~d~%” (box-height item)) When you execute the code, it returns the following result − Length of the Box is 10 Breadth of the Box is 10 Height of the Box is 5 Defining a Class Method The defmethod macro allows you to define a method inside the class. The following example extends our Box class to include a method named volume. Create a new source code file named main.lisp and type the following code in it. Live Demo (defclass box () ((length :accessor box-length) (breadth :accessor box-breadth) (height :accessor box-height) (volume :reader volume) ) ) ; method calculating volume (defmethod volume ((object box)) (* (box-length object) (box-breadth object)(box-height object)) ) ;setting the values (setf item (make-instance ”box)) (setf (box-length item) 10) (setf (box-breadth item) 10) (setf (box-height item) 5) ; displaying values (format t “Length of the Box is ~d~%” (box-length item)) (format t “Breadth of the Box is ~d~%” (box-breadth item)) (format t “Height of the Box is ~d~%” (box-height item)) (format t “Volume of the Box is ~d~%” (volume item)) When you execute the code, it returns the following result − Length of the Box is 10 Breadth of the Box is 10 Height of the Box is 5 Volume of the Box is 500 Inheritance LISP allows you to define an object in terms of another object. This is called inheritance. You can create a derived class by adding features that are new or different. The derived class inherits the functionalities of the parent class. The following example explains this − Example Create a new source code file named main.lisp and type the following code in it. Live Demo (defclass box () ((length :accessor box-length) (breadth :accessor box-breadth) (height :accessor box-height) (volume :reader volume) ) ) ; method calculating volume (defmethod volume ((object box)) (* (box-length object) (box-breadth object)(box-height object)) ) ;wooden-box class inherits the box class (defclass wooden-box (box) ((price :accessor box-price))) ;setting the values (setf item (make-instance ”wooden-box)) (setf (box-length item) 10) (setf (box-breadth item) 10) (setf (box-height item) 5) (setf (box-price item) 1000) ; displaying values (format t “Length of the Wooden Box is ~d~%” (box-length item)) (format t “Breadth of the Wooden Box is ~d~%” (box-breadth item)) (format t “Height of the Wooden Box is ~d~%” (box-height item)) (format t “Volume of the Wooden Box is ~d~%” (volume item)) (format t “Price of the Wooden Box is ~d~%” (box-price item)) When you execute the code, it returns the following result − Length of the Wooden Box is 10 Breadth of the Wooden Box is 10 Height of the Wooden Box is 5 Volume of the Wooden Box is 500 Price of the Wooden Box is 1000 Print Page Previous Next Advertisements ”;

LISP – Lists

LISP – Lists ”; Previous Next Lists had been the most important and the primary composite data structure in traditional LISP. Present day”s Common LISP provides other data structures like, vector, hash table, classes or structures. Lists are single linked lists. In LISP, lists are constructed as a chain of a simple record structure named cons linked together. The cons Record Structure A cons is a record structure containing two components called the car and the cdr. Cons cells or cons are objects are pairs of values that are created using the function cons. The cons function takes two arguments and returns a new cons cell containing the two values. These values can be references to any kind of object. If the second value is not nil, or another cons cell, then the values are printed as a dotted pair enclosed by parentheses. The two values in a cons cell are called the car and the cdr. The car function is used to access the first value and the cdr function is used to access the second value. Example Create a new source code file named main.lisp and type the following code in it. Live Demo (write (cons 1 2)) (terpri) (write (cons ”a ”b)) (terpri) (write (cons 1 nil)) (terpri) (write (cons 1 (cons 2 nil))) (terpri) (write (cons 1 (cons 2 (cons 3 nil)))) (terpri) (write (cons ”a (cons ”b (cons ”c nil)))) (terpri) (write ( car (cons ”a (cons ”b (cons ”c nil))))) (terpri) (write ( cdr (cons ”a (cons ”b (cons ”c nil))))) When you execute the code, it returns the following result − (1 . 2) (A . B) (1) (1 2) (1 2 3) (A B C) A (B C) The above example shows how the cons structures could be used to create a single linked list, e.g., the list (A B C) consists of three cons cells linked together by their cdrs. Diagrammatically, it could be expressed as − Lists in LISP Although cons cells can be used to create lists, however, constructing a list out of nested cons function calls can”t be the best solution. The list function is rather used for creating lists in LISP. The list function can take any number of arguments and as it is a function, it evaluates its arguments. The first and rest functions give the first element and the rest part of a list. The following examples demonstrate the concepts. Example 1 Create a new source code file named main.lisp and type the following code in it. Live Demo (write (list 1 2)) (terpri) (write (list ”a ”b)) (terpri) (write (list 1 nil)) (terpri) (write (list 1 2 3)) (terpri) (write (list ”a ”b ”c)) (terpri) (write (list 3 4 ”a (car ”(b . c)) (* 4 -2))) (terpri) (write (list (list ”a ”b) (list ”c ”d ”e))) When you execute the code, it returns the following result − (1 2) (A B) (1 NIL) (1 2 3) (A B C) (3 4 A B -8) ((A B) (C D E)) Example 2 Create a new source code file named main.lisp and type the following code in it. Live Demo (defun my-library (title author rating availability) (list :title title :author author :rating rating :availabilty availability) ) (write (getf (my-library “Hunger Game” “Collins” 9 t) :title)) When you execute the code, it returns the following result − “Hunger Game” List Manipulating Functions The following table provides some commonly used list manipulating functions. Sr.No. Function & Description 1 car It takes a list as argument, and returns its first element. 2 cdr It takes a list as argument, and returns a list without the first element 3 cons It takes two arguments, an element and a list and returns a list with the element inserted at the first place. 4 list It takes any number of arguments and returns a list with the arguments as member elements of the list. 5 append It merges two or more list into one. 6 last It takes a list and returns a list containing the last element. 7 member It takes two arguments of which the second must be a list, if the first argument is a member of the second argument, and then it returns the remainder of the list beginning with the first argument. 8 reverse It takes a list and returns a list with the top elements in reverse order. Please note that all sequence functions are applicable to lists. Example 3 Create a new source code file named main.lisp and type the following code in it. Live Demo (write (car ”(a b c d e f))) (terpri) (write (cdr ”(a b c d e f))) (terpri) (write (cons ”a ”(b c))) (terpri) (write (list ”a ”(b c) ”(e f))) (terpri) (write (append ”(b c) ”(e f) ”(p q) ”() ”(g))) (terpri) (write (last ”(a b c d (e f)))) (terpri) (write (reverse ”(a b c d (e f)))) When you execute the code, it returns the following result − A (B C D E F) (A B C) (A (B C) (E F)) (B C E F P Q G) ((E F)) ((E F) D C B A) Concatenation of car and cdr Functions The car and cdr functions and their combination allows extracting any particular element/ member of a list. However, sequences of car and cdr functions could be abbreviated by concatenating the letter a for car and d for cdr within the letters c and r. For example we can write cadadr to abbreviate the sequence of function calls – car cdr car cdr. Thus, (cadadr ”(a (c d) (e f g))) will return d Example 4 Create a new source code file named main.lisp and type the following code in it. Live Demo (write (cadadr ”(a (c d) (e f g)))) (terpri) (write (caar (list (list ”a ”b) ”c))) (terpri) (write (cadr (list (list 1 2) (list 3 4)))) (terpri) When you execute the code, it returns the following

LISP – File I/O

LISP – File I/O ”; Previous Next We have discussed about how standard input and output is handled by common LISP. All these functions work for reading from and writing into text and binary files too. Only difference is in this case the stream we use is not standard input or output, but a stream created for the specific purpose of writing into or reading from files. In this chapter we will see how LISP can create, open, close text or binary files for their data storage. A file represents a sequence of bytes, does not matter if it is a text file or binary file. This chapter will take you through important functions/macros for the file management. Opening Files You can use the open function to create a new file or to open an existing file. It is the most basic function for opening a file. However, the with-open-file is usually more convenient and more commonly used, as we will see later in this section. When a file is opened, a stream object is constructed to represent it in the LISP environment. All operations on the stream are basically equivalent to operations on the file. Syntax for the open function is − open filename &key :direction :element-type :if-exists :if-does-not-exist :external-format where, The filename argument is the name of the file to be opened or created. The keyword arguments specify the type of stream and error handling ways. The :direction keyword specifies whether the stream should handle input, output, or both, it takes the following values − :input – for input streams (default value) :output – for output streams :io – for bidirectional streams :probe – for just checking a files existence; the stream is opened and then closed. The :element-type specifies the type of the unit of transaction for the stream. The :if-exists argument specifies the action to be taken if the :direction is :output or :io and a file of the specified name already exists. If the direction is :input or :probe, this argument is ignored. It takes the following values − :error – it signals an error. :new-version – it creates a new file with the same name but larger version number. :rename – it renames the existing file. :rename-and-delete – it renames the existing file and then deletes it. :append – it appends to the existing file. :supersede – it supersedes the existing file. nil – it does not create a file or even a stream just returns nil to indicate failure. The :if-does-not-exist argument specifies the action to be taken if a file of the specified name does not already exist. It takes the following values − :error – it signals an error. :create – it creates an empty file with the specified name and then uses it. nil – it does not create a file or even a stream, but instead simply returns nil to indicate failure. The :external-format argument specifies an implementation-recognized scheme for representing characters in files. For example, you can open a file named myfile.txt stored in the /tmp folder as − (open “/tmp/myfile.txt”) Writing to and Reading from Files The with-open-file allows reading or writing into a file, using the stream variable associated with the read/write transaction. Once the job is done, it automatically closes the file. It is extremely convenient to use. It has the following syntax − with-open-file (stream filename {options}*) {declaration}* {form}* filename is the name of the file to be opened; it may be a string, a pathname, or a stream. The options are same as the keyword arguments to the function open. Example 1 Create a new source code file named main.lisp and type the following code in it. (with-open-file (stream “/tmp/myfile.txt” :direction :output) (format stream “Welcome to Tutorials Point!”) (terpri stream) (format stream “This is a tutorials database”) (terpri stream) (format stream “Submit your Tutorials, White Papers and Articles into our Tutorials Directory.”) ) Please note that all input-output functions discussed in the previous chapter, such as, terpri and format are working for writing into the file we created here. When you execute the code, it does not return anything; however, our data is written into the file. The :direction :output keywords allows us do this. However, we can read from this file using the read-line function. Example 2 Create a new source code file named main.lisp and type the following code in it. (let ((in (open “/tmp/myfile.txt” :if-does-not-exist nil))) (when in (loop for line = (read-line in nil) while line do (format t “~a~%” line)) (close in) ) ) When you execute the code, it returns the following result − Welcome to Tutorials Point! This is a tutorials database Submit your Tutorials, White Papers and Articles into our Tutorials Directory. Closing File The close function closes a stream. Print Page Previous Next Advertisements ”;

LISP – Vectors

LISP – Vectors ”; Previous Next Vectors are one-dimensional arrays, therefore a subtype of array. Vectors and lists are collectively called sequences. Therefore all sequence generic functions and array functions we have discussed so far, work on vectors. Creating Vectors The vector function allows you to make fixed-size vectors with specific values. It takes any number of arguments and returns a vector containing those arguments. Example 1 Create a new source code file named main.lisp and type the following code in it. Live Demo (setf v1 (vector 1 2 3 4 5)) (setf v2 #(a b c d e)) (setf v3 (vector ”p ”q ”r ”s ”t)) (write v1) (terpri) (write v2) (terpri) (write v3) When you execute the code, it returns the following result − #(1 2 3 4 5) #(A B C D E) #(P Q R S T) Please note that LISP uses the #(…) syntax as the literal notation for vectors. You can use this #(… ) syntax to create and include literal vectors in your code. However, these are literal vectors, so modifying them is not defined in LISP. Therefore, for programming, you should always use the vector function, or the more general function make-array to create vectors you plan to modify. The make-array function is the more generic way to create a vector. You can access the vector elements using the aref function. Example 2 Create a new source code file named main.lisp and type the following code in it. Live Demo (setq a (make-array 5 :initial-element 0)) (setq b (make-array 5 :initial-element 2)) (dotimes (i 5) (setf (aref a i) i)) (write a) (terpri) (write b) (terpri) When you execute the code, it returns the following result − #(0 1 2 3 4) #(2 2 2 2 2) Fill Pointer The make-array function allows you to create a resizable vector. The fill-pointer argument of the function keeps track of the number of elements actually stored in the vector. It”s the index of the next position to be filled when you add an element to the vector. The vector-push function allows you to add an element to the end of a resizable vector. It increases the fill-pointer by 1. The vector-pop function returns the most recently pushed item and decrements the fill pointer by 1. Example Create a new source code file named main.lisp and type the following code in it. Live Demo (setq a (make-array 5 :fill-pointer 0)) (write a) (vector-push ”a a) (vector-push ”b a) (vector-push ”c a) (terpri) (write a) (terpri) (vector-push ”d a) (vector-push ”e a) ;this will not be entered as the vector limit is 5 (vector-push ”f a) (write a) (terpri) (vector-pop a) (vector-pop a) (vector-pop a) (write a) When you execute the code, it returns the following result − #() #(A B C) #(A B C D E) #(A B) Vectors being sequences, all sequence functions are applicable for vectors. Please consult the sequences chapter, for vector functions. Print Page Previous Next Advertisements ”;

LISP – Set

LISP – Set ”; Previous Next Common Lisp does not provide a set data type. However, it provides number of functions that allows set operations to be performed on a list. You can add, remove, and search for items in a list, based on various criteria. You can also perform various set operations like: union, intersection, and set difference. Implementing Sets in LISP Sets, like lists are generally implemented in terms of cons cells. However, for this very reason, the set operations get less and less efficient the bigger the sets get. The adjoin function allows you to build up a set. It takes an item and a list representing a set and returns a list representing the set containing the item and all the items in the original set. The adjoin function first looks for the item in the given list, if it is found, then it returns the original list; otherwise it creates a new cons cell with its car as the item and cdr pointing to the original list and returns this new list. The adjoin function also takes :key and :test keyword arguments. These arguments are used for checking whether the item is present in the original list. Since, the adjoin function does not modify the original list, to make a change in the list itself, you must either assign the value returned by adjoin to the original list or, you may use the macro pushnew to add an item to the set. Example Create a new source code file named main.lisp and type the following code in it. Live Demo ; creating myset as an empty list (defparameter *myset* ()) (adjoin 1 *myset*) (adjoin 2 *myset*) ; adjoin did not change the original set ;so it remains same (write *myset*) (terpri) (setf *myset* (adjoin 1 *myset*)) (setf *myset* (adjoin 2 *myset*)) ;now the original set is changed (write *myset*) (terpri) ;adding an existing value (pushnew 2 *myset*) ;no duplicate allowed (write *myset*) (terpri) ;pushing a new value (pushnew 3 *myset*) (write *myset*) (terpri) When you execute the code, it returns the following result − NIL (2 1) (2 1) (3 2 1) Checking Membership The member group of functions allows you to check whether an element is member of a set or not. The following are the syntaxes of these functions − member item list &key :test :test-not :key member-if predicate list &key :key member-if-not predicate list &key :key These functions search the given list for a given item that satisfies the test. If no such item is found, then the functions returns nil. Otherwise, the tail of the list with the element as the first element is returned. The search is conducted at the top level only. These functions could be used as predicates. Example Create a new source code file named main.lisp and type the following code in it. Live Demo (write (member ”zara ”(ayan abdul zara riyan nuha))) (terpri) (write (member-if #”evenp ”(3 7 2 5/3 ”a))) (terpri) (write (member-if-not #”numberp ”(3 7 2 5/3 ”a ”b ”c))) When you execute the code, it returns the following result − (ZARA RIYAN NUHA) (2 5/3 ”A) (”A ”B ”C) Set Union The union group of functions allows you to perform set union on two lists provided as arguments to these functions on the basis of a test. The following are the syntaxes of these functions − union list1 list2 &key :test :test-not :key nunion list1 list2 &key :test :test-not :key The union function takes two lists and returns a new list containing all the elements present in either of the lists. If there are duplications, then only one copy of the member is retained in the returned list. The nunion function performs the same operation but may destroy the argument lists. Example Create a new source code file named main.lisp and type the following code in it. Live Demo (setq set1 (union ”(a b c) ”(c d e))) (setq set2 (union ”(#(a b) #(5 6 7) #(f h)) ”(#(5 6 7) #(a b) #(g h)) :test-not #”mismatch) ) (setq set3 (union ”(#(a b) #(5 6 7) #(f h)) ”(#(5 6 7) #(a b) #(g h))) ) (write set1) (terpri) (write set2) (terpri) (write set3) When you execute the code, it returns the following result − (A B C D E) (#(F H) #(5 6 7) #(A B) #(G H)) (#(A B) #(5 6 7) #(F H) #(5 6 7) #(A B) #(G H)) Please Note The union function does not work as expected without :test-not #”mismatch arguments for a list of three vectors. This is because, the lists are made of cons cells and although the values look same to us apparently, the cdr part of cells does not match, so they are not exactly same to LISP interpreter/compiler. This is the reason; implementing big sets are not advised using lists. It works fine for small sets though. Set Intersection The intersection group of functions allows you to perform intersection on two lists provided as arguments to these functions on the basis of a test. The following are the syntaxes of these functions − intersection list1 list2 &key :test :test-not :key nintersection list1 list2 &key :test :test-not :key These functions take two lists and return a new list containing all the elements present in both argument lists. If either list has duplicate entries, the redundant entries may or may not appear in the result. Example Create a new source code file named main.lisp and type the following code in it. Live Demo (setq set1 (intersection ”(a b c) ”(c d e))) (setq set2 (intersection ”(#(a b) #(5 6 7) #(f h)) ”(#(5 6 7) #(a b) #(g h)) :test-not #”mismatch) ) (setq set3 (intersection ”(#(a b) #(5 6 7) #(f h)) ”(#(5 6 7) #(a b) #(g h))) ) (write set1) (terpri) (write set2) (terpri) (write set3) When you execute the code, it returns the following result − (C) (#(A B) #(5 6 7)) NIL The intersection function is

LISP – Loops

LISP – Loops ”; Previous Next There may be a situation, when you need to execute a block of code numbers of times. A loop statement allows us to execute a statement or group of statements multiple times and following is the general form of a loop statement in most of the programming languages. LISP provides the following types of constructs to handle looping requirements. Click the following links to check their detail. Sr.No. Construct & Description 1 loop The loop construct is the simplest form of iteration provided by LISP. In its simplest form, it allows you to execute some statement(s) repeatedly until it finds a return statement. 2 loop for The loop for construct allows you to implement a for-loop like iteration as most common in other languages. 3 do The do construct is also used for performing iteration using LISP. It provides a structured form of iteration. 4 dotimes The dotimes construct allows looping for some fixed number of iterations. 5 dolist The dolist construct allows iteration through each element of a list. Gracefully Exiting From a Block The block and return-from allows you to exit gracefully from any nested blocks in case of any error. The block function allows you to create a named block with a body composed of zero or more statements. Syntax is − (block block-name( … … )) The return-from function takes a block name and an optional (the default is nil) return value. The following example demonstrates this − Example Create a new source code file named main.lisp and type the following code in it − Live Demo (defun demo-function (flag) (print ”entering-outer-block) (block outer-block (print ”entering-inner-block) (print (block inner-block (if flag (return-from outer-block 3) (return-from inner-block 5) ) (print ”This-wil–not-be-printed)) ) (print ”left-inner-block) (print ”leaving-outer-block) t) ) (demo-function t) (terpri) (demo-function nil) When you click the Execute button, or type Ctrl+E, LISP executes it immediately and the result returned is − ENTERING-OUTER-BLOCK ENTERING-INNER-BLOCK ENTERING-OUTER-BLOCK ENTERING-INNER-BLOCK 5 LEFT-INNER-BLOCK LEAVING-OUTER-BLOCK Print Page Previous Next Advertisements ”;

LISP – Decisions

LISP – Decision Making ”; Previous Next Decision making structures require that the programmer specify one or more conditions to be evaluated or tested by the program, along with a statement or statements to be executed if the condition is determined to be true, and optionally, other statements to be executed if the condition is determined to be false. Following is the general form of a typical decision making structure found in most of the programming languages − LISP provides following types of decision making constructs. Click the following links to check their detail. Sr.No. Construct & Description 1 cond This construct is used for used for checking multiple test-action clauses. It can be compared to the nested if statements in other programming languages. 2 if The if construct has various forms. In simplest form it is followed by a test clause, a test action and some other consequent action(s). If the test clause evaluates to true, then the test action is executed otherwise, the consequent clause is evaluated. 3 when In simplest form it is followed by a test clause, and a test action. If the test clause evaluates to true, then the test action is executed otherwise, the consequent clause is evaluated. 4 case This construct implements multiple test-action clauses like the cond construct. However, it evaluates a key form and allows multiple action clauses based on the evaluation of that key form. Print Page Previous Next Advertisements ”;