LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 03-28-2008, 03:31 PM   #1
raskol
Member
 
Registered: Mar 2008
Posts: 51

Rep: Reputation: 15
Help: Problem writing simple LISP-function!


using cormanlisp, trying to write a function that inverses a word, hello becomes olleh etc.
the macro while is from the book ansi common lisp by paul graham so should work. are the warnings standard or is something wrong?
not sure about the " ' "-symbol before "(do" in the while-macro because in the book it is not the same symbol as he uses for lists, '(a b c d).
what is exactly the problem here? what si the prob with test? what do i need to change?

is inverseword correct and will work?

(defmacro while (test rest body)
'(do ()
((not ,test))
,@body))
;;; Warning: Unused variable BODY in anonymous function
;;; Warning: Unused variable REST in anonymous function
;;; Warning: Unused variable TEST in anonymous function
WHILE


(defun inverseword (word)
(setf x word)
(setf y 'nil)
(while (x)
(cons (car x) y)))
;;; Warning: Symbol X assumed special
;;; Warning: Symbol Y assumed special
;;; Warning: Function not defined: %COMMA
;;; Warning: Symbol TEST assumed special
;;; Warning: Function not defined: %COMMA-ATSIGN
;;; Warning: Symbol BODY assumed special
INVERSEWORD


(inverseword '(h e j))
;;; An error of type UNBOUND-VARIABLE was detected in function INVERSEWORD:
;;; Error: The variable TEST is unbound
;;; Entering Corman Lisp debug loop.
;;; Use :C followed by an option to exit. Type :HELP for help.
;;; Restart options:
;;; 1 Abort to top level.
 
Old 03-28-2008, 03:57 PM   #2
abolishtheun
Member
 
Registered: Mar 2008
Posts: 183

Rep: Reputation: 31
The problem with your inverse-word is that you're pulling x and y out of thin air. What are x and y? You never declared them anywhere, so of course Corman chokes. And cons doesn't push new values onto a location, you use push for that.

Here's a few to get you started:

Code:
(defun reverse-list (list)
  "Imperative, basically what you'd write in C"
  (let ((accum nil))
    (dolist (x list)
      (push x list))
    accum))

(defun reverse-list2 (list &optional accum)
  "Tail Recursive"
  (if (null list)
      accum
      (reverse-list2 (cdr list) (cons (car list) accum))))

(defun reverse-list3 (list)
  "With higher order function"
  (reduce #'(lambda (x y) (cons y x)) list :initial-value nil))

(defun reverse-list4 (list)
  "Wasteful recursive"
  (if (null list)
      list
      (append (reverse-list4 (cdr list)) (list (car list)))))
 
Old 03-28-2008, 05:54 PM   #3
raskol
Member
 
Registered: Mar 2008
Posts: 51

Original Poster
Rep: Reputation: 15
ty for those.

i thought i declared them sufficiently by just using setf. in the while-loop is x and y not the same x and y as a few lines above?



and is the while-macro ok?
 
Old 03-28-2008, 06:20 PM   #4
abolishtheun
Member
 
Registered: Mar 2008
Posts: 183

Rep: Reputation: 31
When you call setf on a variable that aren't in scope, Lisp assume it's a dynamically scoped special variable, not what you want. If you want to create "temporary" variables, use the 'let' construct.

What you were probably going for is this:
Code:
(defun inverseword (word)
    (let ((x word) ; set up local variables
          (y nil))
       (while x ; no paren around x, b/c otherwise 
                ; we're calling a function called 'x'
         (push (car x) y)
         (setf x (cdr x)))
       y)) ; return it

(inverseword '(h e j)) ; Returns '(J E H)
This is essentially equivalent to the 'imperative' version I gave earlier, though I use the 'dolist' construct to iterate though lists instead of manually setf-ing x.

And no the while macro is not ok... the apostrophe should be a backtick. and 'rest' should be '&rest' or '&body' (they're equivalent).

Code:
(defmacro while (test &body body)
  `(do ()
     ((not ,test))
    ,@body))

(let ((x 0))
  (while (< x 10)
    (print x)
    (incf x))) ; prints 0 through 9
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Make a function a constant part of LISP? raskol Programming 1 03-28-2008 03:23 PM
Emacs LISP - function and keymap? jantman Programming 5 09-28-2006 11:59 AM
Slow file writing with 'fwrite' function in C-code... scho Programming 5 08-07-2006 12:42 AM
LISP or COMON LISP Compiler for Debian carspidey Programming 3 04-19-2006 07:46 AM
writing a script to perform a function on each users mail folder jhill Linux - Newbie 2 08-24-2004 07:18 AM


All times are GMT -5. The time now is 04:03 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration