Develop Lisp applications using the Cusp Eclipse plug-in

Lisp isn't just for artificial intelligence anymore -- Try it and you may think of Java and C programming differently

Lisp is an excellent programming language that allows you to expand your knowledge of programming languages due to its largely typeless nature. It can also help those seasoned in the Java™ programming language, PHP, or C/C++ think in new ways when developing applications. In addition, you can do some pretty cool things with Lisp. Find out how to develop Lisp applications using the Cusp Eclipse plug-in.

Tyler Anderson (tyleranderson5@yahoo.com), Freelance writer

Tyler Anderson graduated with a degree in Computer Science from Brigham Young University in 2004 and is currently in his last semester as a Master of Science student in Computer Engineering. In the past, he worked as a database programmer for DPMG.COM, and he is currently an engineer for Stexar Corp., based in Beaverton, Oregon.



09 October 2007

Also available in Russian Japanese

Cusp, an Eclipse development environment for Lisp

Cusp is a development environment for the Common Lisp programming language. Using Lisp, you can develop all sorts of applications, including Web applications. Lisp is the second oldest programming language still used widely today (after Fortran) and is known as the first functional language. The creation of Lisp began in the late 1950s and was first implemented in 1958 by the MIT Artificial Intelligence (AI) Project. Its strength is in the processing of lists: AI and symbol mathematics. In fact, Lisp is short for "list processor," which was the need under which this programming language was created, as you'll see in the following paragraphs (see Resources for Lisp historical information).

You'll notice that Lisp is not at all like other general programming languages. For example, in most general programming languages, you perform multiplication just as you would on paper: int times = 5 * 5;.

With Lisp, the following would produce 75: (* 5 5 3). The maximum in this list: (MAX 9 8 7 6 20) returns 20.

Notice that the phrase "first functional language" here is apt, as everything is based on functions. Each function can have a variable number of parameters. The processing of these lists using recursion and Lisp functions like car and cdr is the power of list processing using Lisp.

Given Lisp's age, you can find many development environments for it. However, also inherent to old programming languages, the tool support is mostly text-based and not intuitive for newcomers. Thus, one reason to try Cusp is that it has an intuitive GUI for newcomers to learn and develop Lisp in, rather than a text-based "try-to-remember-all-of-these-commands" type of interface. It also has the advantage of the superb project management features inherent in the Eclipse GUI framework.

Before going on, you'll need to download the latest Eclipse classic bundle from Eclipse.org. Then you'll learn how to install and set up Cusp.


Installing Cusp

You should now have a zipped-up archive of the Eclipse classic bundle. Un-archive it and run eclipse.exe.

To get the latest version of Cusp: click Help > Software Updates > Find and Install. Click the Search for new features to install option. Now click the New Remote Site button. Type the name as Cusp update site and the URL as http://www.sergeykolos.com/cusp/update, and click OK (see Figure 1).

Figure 1. Entering remote site information for Cusp
Entering remote site information for Cusp

Click the checkbox next to the new remote site you added and click Finish (see Figure 2).

Figure 2. Selecting the Cusp Eclipse Update Site
Selecting the Cusp Eclipse Update Site

You'll be brought to another window where you need to expand the Cusp Eclipse Update Site and select Cusp, as shown below.

Figure 3. Selecting features to install
Selecting features to install

Click Next. Then read and accept the license agreement by clicking I accept the terms in the license agreement and click Next. Make sure all the libraries are selected, as shown below, and click Next again.

Figure 4. Selecting optional features
Selecting optional features

The last page gives you an installation summary of the features you're about to install. Click Finish. The plug-in and its components will download and install. After the download, you'll get a warning saying that you're about to install an unsigned feature. Click Install all. At the end of the installation, you'll be asked to restart Eclipse; click Yes.

You've installed the Eclipse Cusp plug-in. Next, you'll set up a Lisp project.


Setting up a Lisp project

Before Lisp development can begin, you need to set up a new Lisp project. You can do so by going to File > New > Project. Expand the Lisp folder, click Lisp Project, and click Next. Choose a name for the new project, my_new_lisp_project, as shown below, then click Finish.

Figure 5. Naming your new Lisp project
Naming your new Lisp project

After clicking Finish, your new project gets created and the Lisp perspective opens, as shown below.

Figure 6. The Lisp perspective
The Lisp perspective

Behold the Lisp perspective. The Lisp Navigator window shows your open project, along with its associated files. The Outline window shows an outline of the currently open file. The top-right window, showing main.lisp, is the Lisp development window. The bottom-right window, REPL, is the command-line Lisp interpreter, where you can run Lisp commands.

In the event you close Eclipse and reopen it, you'll need to load your projects .asd file, as shown below.

Figure 7. Loading your ASD file
Loading your ASD file

Note that you need to right click the my_new_lisp_project.asd file under the my_new_lisp_project folder and select Load asd. What this essentially does is compile your Lisp project in the REPL window, allowing you to enter Lisp commands that can use your new code.

Next, you'll try out some Lisp development using Cusp.


Lisp development using Cusp

First, you'll define a simple custom function and test it, as well. Open the main.lisp file and, using the defun (define function) command, and add the following:

...
(defun first_howdy_function ()
  "howdy ho")

Save the file. To export the function from within the package, type the following code in defpackage.lisp:

...
   ;; Exported symbols go here
  first_howdy_function
   ))

The function can be used from outside the package. To test your new function, type the following in the lower window of REPL: (my_new_lisp_project:first_howdy_function).

Note that for the scope you're in, this is the same as entering (my_new_lisp_project::first_howdy_function). This is what you would have to type if you didn't export the function in defpackage.lisp.

Click Send and check out the output. The output from entering either of the above commands is as follows:

COMMON-LISP-USER>
(my_new_lisp_project:first_howdy_function)

"howdy ho"

There you have it: your first Lisp Howdy function.

Try an echo function with an input to it:

...
(defun first_echo_function (echoval)
  echoval)

As with the last function, export it in defpackage.lisp. You'll test this first_echo_function by typing the following in the lower portion of the REPL window: (my_new_lisp_project:first_echo_function '("howd" "y h" "o")). Note that the '("howd" "y h" "o") portion is the syntax for defining a list. First, the single quote must precede the parentheses, then the list elements are defined within the parentheses. The output is shown below:

COMMON-LISP-USER>
(my_new_lisp_project:first_echo_function '("howd" "y h" "o"))

("howd" "y h" "o")

You'll create a method to process each list element individually, which is the true power of Lisp. Define it as follows:

(defmethod concat2 ((str1 string) (str2 string))
  (concatenate 'string str1 str2))

Note that the above method actually defines a type string. Up to now, you've been using Lisp as a largely typeless language. Though the double quotes implicitly types data as strings, the above method explicitly types both the input and output to the concat2 function as strings. This method also uses the built-in concatenate function to combine two strings and return them as a single string.

To test concat2, export it, then type (my_new_lisp_project:concat2 "howd" "y ho"). Its output is as follows:

Listing 7. The output of concatenating two strings
COMMON-LISP-USER>
(my_new_lisp_project:concat2 "howd" "y ho")

"howdy ho"

There you have it. The strings "howd" and "y ho" become "howdy ho." Now you'll create a more generalized concatenation function using the two functions Lisp is famous for: car and cdr.

Listing 1. Concatenating three elements in a list
(defun concat3 (args_list)
  (concat2 (car args_list)
           (concat2 (car (cdr args_list))
                    (car (cdr (cdr args_list))))))

Note that this function still uses the concat2 function, but takes as its input a parameter list. Take note of how each section of the concatenation is retrieved from args_list. The car takes the first element from the list. The cdr returns the list minus the first element. You can see how you'd get the first element by just calling the car function on the list. Obtaining the second element requires calling the cdr on the list, then the car on the new list. The third element is taken by calling the cdr on the list twice and calling car on the final list.

The output of the above function after exporting it is as follows:

COMMON-LISP-USER>
(my_new_lisp_project:concat3 '("howd" "y h" "o"))

"howdy ho"

And there you go. The three strings were concatenated correctly to produce "howdy ho." Next, you'll create a recursive function.


Recursion using Lisp

The last function you're going to create is going to take some recursion, where the true power of list processing using Lisp lies. Iteration is possible (looping through each item one by one), but unlike general languages like the Java language, recursion is by far the easiest way to process lists in Lisp. You'll know exactly what recursion is by the end of this section.

Begin by creating a recursive concat function.

Listing 2. Recursive concatenation (unlimited parameters)
1   (defun concat_recursive (args_list)
2     (if (equal (cdr args_list) nil)
3         (car args_list)
4         (concat2 (car args_list)
5                  (concat_recursive (cdr args_list)))))

Recursion can be a difficult concept to tackle, so lets walk through this one:

  • Assume an arbitrary argument list is passed to the above function.
  • If there is only one element in the list (the (cdr args_list) portion on line 2 returns nil), return the single element (the (car args_list) on line 3).
  • If there is more than one element in the list (meaning the (cdr args_list) portion on line 2 did not return nil), return the result of concatenating (using concat2) the first element of the list (see line 4) and the result of recursively calling concat_recursive using the result of (cdr args_list) as parameters (see line 5).

When passing the following list as a parameter, '("ho" "wd" "y" " h" "o"), the following is a walk-through of the output:

  • The first time line 2 is reached, the if statement is false, and concat2 is called with "ho" and (concat_recursive '("wd" "y" " h" "o")).
  • The second time line 2 is reached, the if statement is again false, and concat2 is called with "wd" and (concat_recursive '("y" " h" "o")).
  • The third time line 2 is reached, the if statement is again false, and concat2 is called with "y" and (concat_recursive '(" h" "o")).
  • The fourth time line 2 is reached, the if statement is again false, and concat2 is called with " h" and (concat_recursive '("o")).
  • The fifth time is the magical time when the recursion ends. This is because this time, the if statement on line 2 is now true, and "o" is simply returned. The recursion unwinds as follows:
    • Fourth time: " h" and "o" are concatenated and returned.
    • Third time: "y" and " ho" are concatenated and returned.
    • Second time: "wd" and "y ho" are concatenated and returned.
    • First time: "ho" and "wdy ho" are concatenated and returned as the final result.

And there you have it — "howdy ho" ultimately gets returned, as shown below:

COMMON-LISP-USER>
(my_new_lisp_project:concat_recursive '("ho" "wd" "y" " h" "o"))

"howdy ho"

You have added recursion to your Cusp development arsenal. Try out the debugger next.


Debugging using Cusp

Think of input conditions that will cause concat_recursive to fail, so that the debugger might come in handy. One is that you could send a number mixed in with the strings to see what happens. Remember that the concatenation using concat2 requires two strings, so a number will cause this function to break within the recursion.

Type the following command: (my_new_lisp_project:concat_recursive '("ho" "wd" "y" 55 " h" "o")). Note the number 55 without being enclosed in double quotes is not a string and will cause the debugger to appear, as shown below.

Figure 8. Triggering the debugger
Triggering the debugger

Notice the main error triggering the debugger is that concat2 cannot be called on the list: (55 " ho"). Also notice that the " h" and "o" were already concatenated before the error got triggered.

In the debugger window, you can also see the ==Backtrace==, shown in Figure 8. Each of the lines underneath it (0-19, in this case) give a detailed trace from when you click Send to the occurring fault. Here, you can also see and follow the recursion leading up to the numeric 55 that triggered the fault.

What now? You have three options in the above case to exit the debugger, and to modify and validate your input to the function: You can abort the command and return to the regular REPL window; you can close the connection (via testing, it's found you'll need to reboot Eclipse to restart the Lisp processor if you choose this option); or you can simply abort the debugger and return to the regular REPL window. The best option to exit the debugger is always to abort the command and return to the regular REPL window.

There you have it. You've implemented a recursive function in Lisp.


Summary

You completed this Lisp development using the Cusp Eclipse plug-in successfully. You should now know why Lisp is so powerful. Through simple recursive statements, you can power process lists of symbols and data easily. Cusp complements the capabilities of Lisp with the help of the built-in Cusp debugger, a solid GUI with project management capabilities, an interactive Lisp editor, and the command-line interface to the Lisp processor where you can enter commands and test your code. Be sure to review the Resources for more information.


Download

DescriptionNameSize
Cusp article sample codeos-eclipse-lispcusp.code.zip28KB

Resources

Learn

Get products and technologies

Discuss

  • The Eclipse Platform newsgroups should be your first stop to discuss questions regarding Eclipse. (Selecting this will launch your default Usenet news reader application and open eclipse.platform.)
  • The Eclipse newsgroups has many resources for people interested in using and extending Eclipse.
  • Participate in developerWorks blogs and get involved in the developerWorks community.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Open source on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=259730
ArticleTitle=Develop Lisp applications using the Cusp Eclipse plug-in
publish-date=10092007