=== Lab 1 material: Introduction to Lisp === * [[http://cs.gmu.edu/~sean/lisp/LispTutorial.html|Lisp Tutorial]] * [[http://www.gigamonkeys.com/book/lispbox/|LispBox - easy one-install Lisp implementations]], Locally:[[http://www.ru.is/faculty/hannes/share/lispbox07.exe|lispbox07.exe]] [[http://www.ru.is/faculty/hannes/share/Lispbox-0.7-with-acl81_express.dmg|Lispbox-0.7-with-acl81_express.dmg (OS X 10.4 PPC)]] * [[http://www.apl.jhu.edu/~hall/Lisp-Notes/Introductory-Lisp-Overview.ps|Lisp cheat sheet (PS)]] {{:public:t-622-arti-09-1:introductory-lisp-overview.pdf|(PDF)}} * More material for learning Lisp: * [[http://mypage.iu.edu/~colallen/lp/|Lisp Primer]] - A tutorial * [[http://gigamonkeys.com/book/|Practical Common Lisp]] - A freely available book on Lisp * [[http://refcards.com/docs/wingb/xemacs/xemacs-refcard-a4.pdf|Emacs reference card (PDF)]] To work through these exercises, refer to the above material for more information. - **Emacs and REPL:**\\ Install [[http://www.gigamonkeys.com/book/lispbox/|LispBox]] on your computer and start it up. The lower window is the Lisp REPL (read-eval-print loop) where you can enter Lisp expressions and have them evaluated. - **Hello World:**\\ Type an expression prints "Hello World!" on the screen. \\ ;; A typical print expression (print "Here is some text") Note that in the REPL, you can recall your last command with Alt+P (for //previous//) and that tab completion works on most lisp symbols. - **Lisp basics:**\\ Go through the sections //Evaluating simple expressions//, //Evaluating Lists as Functions// and //Control Structures and Variables// in [[http://cs.gmu.edu/~sean/lisp/LispTutorial.html|this tutorial]]. Some expressions will generate an error, in that case the top window will show a message and a list of options. The safe option is always ''[ABORT REQUEST]''. - **Defining functions:**\\ Go through the section //Writing Functions// in the tutorial. You can skip typing the examples in boxes 3, 5, 6, 7, 8 and 9 - but read the examples and try to understand them. Write a function that asks the user for their name and prints "Hello, !" on the screen. \\ ;; An example of getting input from a user and printing it (defun repeat-what-you-say () (let ((what-you-said)) (print "Please say something and type enter:") (setf what-you-said (read-line t)) (print (concatenate 'string "You said: " what-you-said)))) Note that in the REPL, you will see the printed output **as well as** the return value of the function. The return value is (as you should know by now) the result of the last expression of the function body. Since the ''PRINT'' function returns its argument, the function above also returns it, which is why it is printed twice in the REPL. - **Lists as data:** \\ So far we've only seen lists used to call functions. However they can also be used to store data. Go through the section //Lists and Symbols as Data// in the tutorial. Feel free to skip the exercises that you feel you understand well, but make sure you understand how quoting (e.g. '''(1 2 3)'') works. \\ The tutorial does not talk about keyword lists, which we will use. Keyword lists are created with the following syntax: \\ '(:keyword "value" :numberfield 123) You can access the fields of a keyword list with the ''GETF'' function: \\ CL-USER> (getf '(:a 1 :b 2 :c 3) :b) 2 You can read more about keyword lists in [[http://gigamonkeys.com/book/practical-a-simple-database.html#cds-and-records|chapter 2 of Practical Common Lisp]]. For more information about quoting, see [[http://mypage.iu.edu/~colallen/lp/node9.html|this page of the Lisp Primer]], and remember that quoting simply prevents a list from being //evaluated// and instead treats it as data. - **Symbols as data:** \\ Lisp allows us to use symbols (e.g. variable names) as data. They are created with the same quoting syntax as lists: \\ 'symbol Symbols are simply short strings, except they are case-insensitive (the REPL always prints them in uppercase) and cannot be changed or manipulated. Like with lists, quoting a symbol simply stops it from being evaluated (i.e. treated as a variable) and instead treats the symbol itself as data. \\ Write a function that takes a keyword list, looks up the number called '':test'' and returns the symbol ''YES'' if it is less than 10, and ''NO'' otherwise. \\ ;; Example REPL session showing the concepts you need to use CL-USER> (setf x '(:x 10 :y 33 :test 9)) (:X 10 :Y 33 :TEST 9) CL-USER> (getf x :test) 9 CL-USER> (> (getf x :test) 10) NIL CL-USER> (> 10 (getf x :test)) T CL-USER> (if (> 10 (getf x :test)) 'SMALLER 'BIGGER) SMALLER - **Loading files:** \\ Typing things into the REPL every time is of course not the way we usually use Lisp. Instead we load a file with definitions of functions and variables, and then use the REPL to invoke them. * Start by downloading [[http://gist.github.com/48969|this file]] (right click "raw" and choose save as) and name the file ''agents.lisp''. Save it in a folder for this lab session. * In the REPL, type '','' (comma); this invokes the command mode of the REPL, type the command ''cd'' and press enter. Emacs will prompt you for a file path, enter the file path to the folder where you saved the file. * Now type (in the REPL) the expression ''(load "agents.lisp")''. * Now the definitions of the file have been loaded in the REPL. To see what definitions are available, open the file in the upper half of Emacs. To do this, you can click in the upper half and then press (in sequence) Ctrl+X and Ctrl+F and type the path to the file. Alternatively just select "File -> Open" :-) If Emacs asks you to allow it to apply local variables from the file, then answer with Yes. * Have a look at the file and see if you can understand the code. Don't worry too much if you don't. At the bottom of the file there are three example expressions. Try typing (in order) them in the REPL and see what happens - **Writing an agent program:** \\ The function ''EXAMPLE-AGENT-PROGRAM'' gives an example of how to create a program to control an agent in the vacuum-cleaner world. The program is a function that takes a keyword list representing the percept value, and it should return one of the symbols ''LEFT, RIGHT, UP, DOWN, SUCK'' or ''IDLE''. A percept keyword list looks like this: '(:x 3 :y 8 :dirty T) Here, '':x'' and '':y'' give the location of the agent and '':dirty'' tells us if the current square has dirt or not. The given example program is an implementation of the code in figure 2.8 on page 46 in the textbook. \\ Write a new agent program, that walks about the environment randomly, sucking up dirt where it finds it. You can either write your function in the REPL or add it to the file. If you add it to the file, you have to save the file (keyboard shortcut is Ctrl+X, Ctrl+S) and then reload the file in the REPL (recommended option). Instead of typing the load command again, you can reload the file by hitting Ctrl+C, Ctrl+L while the file window is active. \\ Use the ''SIMULATE'' and ''SIMULATE-QUIET'' functions from last step to test your new agent program. Does it give better performance evaluation than the old one? \\ - **Writing a performance evaluation function:** \\ The function ''EXAMPLE-MEASURE'' shows how performance evaluation functions look. This function takes an environment and an agent as parameters, and returns a number indicating the performance of the agent so far. \\ Both the agent and the environment are so called //structures//. Their fields are defined in the file ''agents.lisp'' with calls to the ''DEFSTRUCT'' macro. This macro defines a function for constructing an instance of the structure, e.g. for the ''ENV'' structure, this function is called ''MAKE-ENV''. \\ The macro also defines functions for accessing the fields of a structure, e.g. the //width// field of an ''ENV'' structure in variable //env// can be accessed with ''(env-width env)''. \\ Write a performance evaluation function that awards 10 points for every clean square but deducts one point for every move the agent makes. The number of moves is stored in the //moves-so-far// field. Now run the simulations again. How does this change the evaluation score? Can you think of ways to change the agent program so that it scores better with this new evaluation function?