Morning,
I have decided to finally learn lisp after many other langauges. I
have chosen a pet project to help with learning lisp. This project
looks at stock market data in different ways (no worries, it hasn't
made any money).
The first step in the new approach for this project and in learning
lisp (clisp 2.43) is to pull a web page at Stock Charts
(http://stockcharts.com). The code I have so far is: (the formatting
is messed up in the copy)
; the url base
(defvar *host* "http://stockcharts.com")
(defun getpage (page)
"get the page at the indicated url"
(let ((url (string-concat *host* page))
(l nil))
(print (string-concat "url='" url "'"))
(ext:with-http-input ((s len) url)
(progn
(if len (print (string-concat "length=" len)))
(do (setq l (read-line s))
(print l))))))
(getpage "/def/servlet/SC.scan")
The output is:
"url='http://stockcharts.com/def/servlet/SC.scan'"
;; connecting to "http://stockcharts.com/def/servlet/SC.scan"...connected...HTTP/1.1 200 OK
*** - EVAL: variable PRINT has no value
shell returned 1
When I execute (print "hello") inside of clisp it works. Why is (print) now not found?
Mike
On 2008-12-29, Mike <·····@mikee.ath.cx> wrote:
> Morning,
>
> I have decided to finally learn lisp after many other langauges. I
> have chosen a pet project to help with learning lisp. This project
> looks at stock market data in different ways (no worries, it hasn't
> made any money).
>
> The first step in the new approach for this project and in learning
> lisp (clisp 2.43) is to pull a web page at Stock Charts
> (http://stockcharts.com). The code I have so far is: (the formatting
> is messed up in the copy)
>
> ; the url base
> (defvar *host* "http://stockcharts.com")
>
> (defun getpage (page)
> "get the page at the indicated url"
> (let ((url (string-concat *host* page))
> (l nil))
> (print (string-concat "url='" url "'"))
> (ext:with-http-input ((s len) url)
> (progn
> (if len (print (string-concat "length=" len)))
> (do (setq l (read-line s))
> (print l))))))
>
> (getpage "/def/servlet/SC.scan")
>
> The output is:
>
> "url='http://stockcharts.com/def/servlet/SC.scan'"
> ;; connecting to "http://stockcharts.com/def/servlet/SC.scan"...connected...HTTP/1.1 200 OK
> *** - EVAL: variable PRINT has no value
>
>
> shell returned 1
>
> When I execute (print "hello") inside of clisp it works. Why is (print) now not found?
>
> Mike
I find I do not get an error modifying the code as:
(defvar *host* "http://stockcharts.com")
(defun getpage (page)
"get the page at the indicated url"
(let ((url (string-concat *host* page))
(l nil))
(print (string-concat "url='" url "'"))
(ext:with-http-input ((s len) url)
(progn
(if len (print (string-concat "length=" len)))
(loop while (setq l (read-line s))
do (print l))))))
(getpage "/def/servlet/SC.scan")
So my error was in the (do ...) attempted loop. When I change the
loop to (loop while ...) it works. Now to parse the returned page
for getting the next page(s).
Mike
On Mon, 29 Dec 2008 01:49:34 +0000, Mike wrote:
> On 2008-12-29, Mike <·····@mikee.ath.cx> wrote:
>> Morning,
>>
>> I have decided to finally learn lisp after many other langauges. I have
>> chosen a pet project to help with learning lisp. This project looks at
>> stock market data in different ways (no worries, it hasn't made any
>> money).
>>
>> The first step in the new approach for this project and in learning
>> lisp (clisp 2.43) is to pull a web page at Stock Charts
>> (http://stockcharts.com). The code I have so far is: (the formatting is
>> messed up in the copy)
>>
>> ; the url base
>> (defvar *host* "http://stockcharts.com")
>>
>> (defun getpage (page)
>> "get the page at the indicated url"
>> (let ((url (string-concat *host* page))
>> (l nil))
>> (print (string-concat "url='" url "'"))
>> (ext:with-http-input ((s len) url)
>> (progn
>> (if len (print (string-concat "length=" len))) (do
>> (setq l (read-line s))
>> (print l))))))
>>
>> (getpage "/def/servlet/SC.scan")
>>
>> The output is:
>>
>> "url='http://stockcharts.com/def/servlet/SC.scan'" ;; connecting to
>> "http://stockcharts.com/def/servlet/SC.scan"...connected...HTTP/1.1 200
>> OK *** - EVAL: variable PRINT has no value
>>
>>
>> shell returned 1
>>
>> When I execute (print "hello") inside of clisp it works. Why is (print)
>> now not found?
>>
>> Mike
>
> I find I do not get an error modifying the code as:
>
> (defvar *host* "http://stockcharts.com")
>
> (defun getpage (page)
> "get the page at the indicated url"
> (let ((url (string-concat *host* page))
> (l nil))
> (print (string-concat "url='" url "'")) (ext:with-http-input ((s
> len) url)
> (progn
> (if len (print (string-concat "length="
> len))) (loop while (setq l (read-line s))
> do (print l))))))
>
> (getpage "/def/servlet/SC.scan")
>
> So my error was in the (do ...) attempted loop. When I change the loop
> to (loop while ...) it works. Now to parse the returned page for
> getting the next page(s).
Hi Mike,
I am glad you are learning Lisp. I see that you have already found your
error. A few suggestions that may help you in the future:
- paste.lisp.org is great for posting code snippets, as some newsreaders
mangle the indentation,
- you should learn about the general debugging tools (step, trace;
sometimes simple format statements help too, also read you
implementation's manual about this),
- learn to navigate the Hyperspec & other docs. I use lispdoc.com with
the Firefox plugin for searching.
Lisp long and prosper,
Tamas
On 2008-12-29, Tamas K Papp <······@gmail.com> wrote:
> On Mon, 29 Dec 2008 01:49:34 +0000, Mike wrote:
>
>> On 2008-12-29, Mike <·····@mikee.ath.cx> wrote:
>>> Morning,
>>>
>>> I have decided to finally learn lisp after many other langauges. I have
>>> chosen a pet project to help with learning lisp. This project looks at
>>> stock market data in different ways (no worries, it hasn't made any
>>> money).
>>>
>>> The first step in the new approach for this project and in learning
>>> lisp (clisp 2.43) is to pull a web page at Stock Charts
>>> (http://stockcharts.com). The code I have so far is: (the formatting is
>>> messed up in the copy)
>>>
>>> ; the url base
>>> (defvar *host* "http://stockcharts.com")
>>>
>>> (defun getpage (page)
>>> "get the page at the indicated url"
>>> (let ((url (string-concat *host* page))
>>> (l nil))
>>> (print (string-concat "url='" url "'"))
>>> (ext:with-http-input ((s len) url)
>>> (progn
>>> (if len (print (string-concat "length=" len))) (do
>>> (setq l (read-line s))
>>> (print l))))))
>>>
>>> (getpage "/def/servlet/SC.scan")
>>>
>>> The output is:
>>>
>>> "url='http://stockcharts.com/def/servlet/SC.scan'" ;; connecting to
>>> "http://stockcharts.com/def/servlet/SC.scan"...connected...HTTP/1.1 200
>>> OK *** - EVAL: variable PRINT has no value
>>>
>>>
>>> shell returned 1
>>>
>>> When I execute (print "hello") inside of clisp it works. Why is (print)
>>> now not found?
>>>
>>> Mike
>>
>> I find I do not get an error modifying the code as:
>>
>> (defvar *host* "http://stockcharts.com")
>>
>> (defun getpage (page)
>> "get the page at the indicated url"
>> (let ((url (string-concat *host* page))
>> (l nil))
>> (print (string-concat "url='" url "'")) (ext:with-http-input ((s
>> len) url)
>> (progn
>> (if len (print (string-concat "length="
>> len))) (loop while (setq l (read-line s))
>> do (print l))))))
>>
>> (getpage "/def/servlet/SC.scan")
>>
>> So my error was in the (do ...) attempted loop. When I change the loop
>> to (loop while ...) it works. Now to parse the returned page for
>> getting the next page(s).
>
> Hi Mike,
>
> I am glad you are learning Lisp. I see that you have already found your
> error. A few suggestions that may help you in the future:
>
> - paste.lisp.org is great for posting code snippets, as some newsreaders
> mangle the indentation,
> - you should learn about the general debugging tools (step, trace;
> sometimes simple format statements help too, also read you
> implementation's manual about this),
> - learn to navigate the Hyperspec & other docs. I use lispdoc.com with
> the Firefox plugin for searching.
>
> Lisp long and prosper,
>
> Tamas
I'm quite comfortable with both gdb and 'perl -d'. Is there anything
like those two for clisp?
I found the next error and am now getting the web output to disk
(just a test). Next I need to insert newlines into the pulled page
so the next (defun ...) can split the input and parse table
(<td>...</td>) values.
Mike
On Mon, 29 Dec 2008 02:13:38 +0000, Mike wrote:
> I'm quite comfortable with both gdb and 'perl -d'. Is there anything
> like those two for clisp?
I don't think so (but I don't know about perl -d). In case of errors,
Lisp signals errors via its condition system, and I would recommend the
PCL book on that. Of course, not all badly written code signals errors,
but most implementations give you hints about certain forms of
incorrectness when you compile the code.
Trace allows you to trace function calls, step will do what its name
suggests :-) Both are worth knowing about.
Are you using SLIME, or some other IDE?
Tamas
On 2008-12-29, Tamas K Papp <······@gmail.com> wrote:
> On Mon, 29 Dec 2008 02:13:38 +0000, Mike wrote:
>
>> I'm quite comfortable with both gdb and 'perl -d'. Is there anything
>> like those two for clisp?
>
> I don't think so (but I don't know about perl -d). In case of errors,
> Lisp signals errors via its condition system, and I would recommend the
> PCL book on that. Of course, not all badly written code signals errors,
> but most implementations give you hints about certain forms of
> incorrectness when you compile the code.
>
> Trace allows you to trace function calls, step will do what its name
> suggests :-) Both are worth knowing about.
>
> Are you using SLIME, or some other IDE?
>
> Tamas
I'm a vi user for decades. I used emacs for a while. Emacs is not
conducive to my style of system administration. Vi is on every unix
machine (mac and I can get it on windows too).
I have the PCL book. I'm finishing a book on XP programming first,
then I'll get to the PCL book. Does the PCL book show how to setup
(step)?
The command 'perl -d' tells perl to enter its own internal debugger
that functions in many ways like gdb.
Mike
On Mon, 29 Dec 2008 02:29:55 +0000, Mike wrote:
> I'm a vi user for decades. I used emacs for a while. Emacs is not
> conducive to my style of system administration. Vi is on every unix
> machine (mac and I can get it on windows too).
OK, I was not pushing you towards Emacs+SLIME. But I can't help with vi
as an environment because I know nothing about it, maybe someone else
will.
> I have the PCL book. I'm finishing a book on XP programming first, then
> I'll get to the PCL book. Does the PCL book show how to setup (step)?
You just evaluate (step form) with the form you want to step, and the
rest is implementation-dependent but should be easy to figure out. The
PCL book is useful for learning Lisp in general.
HTH,
Tamas
Mike <·····@mikee.ath.cx> wrote:
+---------------
| Tamas K Papp <······@gmail.com> wrote:
| > Are you using SLIME, or some other IDE?
|
| I'm a vi user for decades. I used emacs for a while. Emacs is not
| conducive to my style of system administration. Vi is on every unix
| machine (mac and I can get it on windows too).
+---------------
Here are a few small tips on using Vi (or Vim) when editing Lisp:
- Set the following options:
:se ai icl sm mat=2 sw=1
or without the abbreviations:
:set autoindent iclower showmatch matchtime=2 shiftwidth=1
That is, set:
- Autoindent [use ^D or 0^D to cancel some/all of the indenting].
- Ignore case in searches but only if the search string
is all lower case.
- Show ("flash") the open matching paren/bracket/brace
when the closing matching paren/bracket/brace is inserted.
- Set the "flash" time for paren matching to 200 ms (or whatever
time is comfortable for you -- editing across slower speed
network connections may need larger values).
- Set the amount to shift text left/right to one space. [You can
use the "." command to quickly repeat the same shift to get larger
shift amounts.]
- With that done, then you can use the "%" command to bounce back
and force between matching parens; you can place the cursor on
[or on front of] a paren and use ">%" to shift a whole sexp right,
or "<%" to shift it left, or ">%..." to shift a sexp right 4 spaces,
etc.
- "d%" will, of course, delete a whole sexp; "y%" will "yank" (copy) one;
"p" will paste it after the current point [and "P" will paste before].
All of these can be used with prefix Q-register names (e,g, "a etc.)
- Experiment with ":set lisp" and see if it does anything useful
for you. [It might will not, since it was never well-supported.]
- Vim has more Lisp-friendly options than Vi; it might be worth looking
into. [I don't use Vim much, "nvi-1.79" is my standard editor, so I
can't offer much more help there.]
- Create yourself a "map" entry in your "~/.exrc" for some function
key [I use "shift-<F12>" myself] to type ":r!cat^V^M" for you.
That will let you paste hunks of Lisp from somewhere else into
your editing sessions without the autoindenting (turned on above)
messing up the indenting. [And if you have the "xselection" or
"xclip" programs, you can make a "map" entry I use <F12>] that
pastes the current X selection directly, without having to hit
middle-mouse then EOF, as needed with ":r!cat".]
Not much, I know, but should help some...
-Rob
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
On 2008-12-29, Rob Warnock <····@rpw3.org> wrote:
>
> Here are a few small tips on using Vi (or Vim) when editing Lisp:
>
> - Set the following options:
>
> :se ai icl sm mat=2 sw=1
My normal $HOME/.exrc is:
set sm ai lisp
set report=2 ts=4 sw=4
> That is, set:
>
> - Autoindent [use ^D or 0^D to cancel some/all of the indenting].
>
> - Ignore case in searches but only if the search string
> is all lower case.
>
> - Set the "flash" time for paren matching to 200 ms (or whatever
> time is comfortable for you -- editing across slower speed
> network connections may need larger values).
These two I've not used. Thanks.
> - With that done, then you can use the "%" command to bounce back
> and force between matching parens; you can place the cursor on
> [or on front of] a paren and use ">%" to shift a whole sexp right,
> or "<%" to shift it left, or ">%..." to shift a sexp right 4 spaces,
> etc.
>
> - "d%" will, of course, delete a whole sexp; "y%" will "yank" (copy) one;
> "p" will paste it after the current point [and "P" will paste before].
> All of these can be used with prefix Q-register names (e,g, "a etc.)
Even using vi for decades, I've not thought of this particular use of
%. Great idea.
Eventually I think it might be nice to use clisp as an inferior to vim. I
do a lot of :!clisp %<ENTER> when testing things.
Mike
Mike <·····@mikee.ath.cx> wrote:
+---------------
| Rob Warnock <····@rpw3.org> wrote:
| > Here are a few small tips on using Vi (or Vim) when editing Lisp:
| > - Set the following options:
| > :se ai icl sm mat=2 sw=1
|
| My normal $HOME/.exrc is:
| set sm ai lisp
| set report=2 ts=4 sw=4
+---------------
The "ts=4 sw=4", while fine for C, tends to mess things up with
Lisp, IME. Lots of forms in Lisp want indenting by 1 or 2, not 4.
As a result, I've found that "sw=1" works a lot better, *especially*
when combined with ">%" or "<%" and zero or more following ".",
as needed. [Of course, if your "lisp" mode works well for you,
then "Never mind..."]
-Rob
p.s. There are also some external re-indenting programs out there
that you might want to try, that you can pipe a section of code through,
e.g., <http://www.ccs.neu.edu/home/dorai/scmindent/scmindent.html>
[though you would probably want to tweak that a bit for CL]. One can
reformat some sexp with "!%scmindent" [or any other motion command
besides "%", for larger sections].
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
On 2008-12-29, Rob Warnock <····@rpw3.org> wrote:
> Mike <·····@mikee.ath.cx> wrote:
> +---------------
>| Tamas K Papp <······@gmail.com> wrote:
>| > Are you using SLIME, or some other IDE?
>|
>| I'm a vi user for decades. I used emacs for a while. Emacs is not
>| conducive to my style of system administration. Vi is on every unix
>| machine (mac and I can get it on windows too).
> +---------------
>
> Here are a few small tips on using Vi (or Vim) when editing Lisp:
>
Last night I found and changed my $HOME/.exrc to this:
set report=2
set sw=1
set ai sm lisp
map zz {jv%==
Anywhere in a sexp typing 'zz' in command mode causes vim to reformat
the sexp beautifully.
Mike
Mike <·····@mikee.ath.cx> writes:
> On 2008-12-29, Mike <·····@mikee.ath.cx> wrote:
>> Morning,
>> (do (setq l (read-line s))
>> (print l))))))
>> *** - EVAL: variable PRINT has no value
>> When I execute (print "hello") inside of clisp it works. Why is (print) now not found?
>
> I find I do not get an error modifying the code as:
> (loop while (setq l (read-line s))
> do (print l))))))
>
> So my error was in the (do ...) attempted loop. When I change the
> loop to (loop while ...) it works. Now to parse the returned page
> for getting the next page(s).
It's good you found your DO form was invalid, but it's not enough. You
have to find out why. Read clhs DO
In fact, this assumes you've read
http://www.lispworks.com/documentation/HyperSpec/Body/01_d.htm
too, obviously.
(do (setq l (read-line s))
(print l))
means:
1- bind a local lexical variable named SETQ to the value of the variable
named L.
2- test the value of the variable named PRINT (here you get your
error).
3- if PRINT is true, then return the value of the variable named L.
4- if PRINT is NIL, then do nothing
5- call (READ-LINE S) and assign it to the variable named SETQ.
6- go to 2.
Inconsistent? Quite. But that's what you wrote.
--
__Pascal Bourguignon__
On 2008-12-29, Pascal J. Bourguignon <···@informatimago.com> wrote:
>
> (do (setq l (read-line s))
> (print l))
> means:
>
> 1- bind a local lexical variable named SETQ to the value of the variable
> named L.
> 2- test the value of the variable named PRINT (here you get your
> error).
> 3- if PRINT is true, then return the value of the variable named L.
> 4- if PRINT is NIL, then do nothing
> 5- call (READ-LINE S) and assign it to the variable named SETQ.
> 6- go to 2.
>
> Inconsistent? Quite. But that's what you wrote.
>
Thanks for the break down on what I tried to do. I'll read the clhs to
see what (do ...) actually does. The change to (while ...) is working,
so that's good for now.
I forgot to send the code from home to work last night, so I can't play
with my learning test case until I get back home this evening.
Mike
On 2008-12-29, Mike <·····@mikee.ath.cx> wrote:
>
> Thanks for the break down on what I tried to do. I'll read the clhs to
> see what (do ...) actually does. The change to (while ...) is working,
> so that's good for now.
>
> I forgot to send the code from home to work last night, so I can't play
> with my learning test case until I get back home this evening.
>
> Mike
Working on a project at work in PERL I kept thinking that a lot of
what I'm having to code could be handled by common lisp macros. :(
Mike
On Mon, 29 Dec 2008 01:49:34 +0000, Mike wrote:
> I find I do not get an error modifying the code as:
>
> (defvar *host* "http://stockcharts.com")
>
> (defun getpage (page)
> "get the page at the indicated url"
> (let ((url (string-concat *host* page))
> (l nil))
> (print (string-concat "url='" url "'")) (ext:with-http-input ((s
> len) url)
> (progn
> (if len (print (string-concat "length="
> len))) (loop while (setq l (read-line s))
> do (print l))))))
this is lispier and shorter:
(defun getpage (page)
"Get the page at the indicated url"
(let ((url (string-concat *host* page)))
(format t "url='~A'" url)
(ext:with-http-input ((s len) url)
(when len (format t "length=~A" len))
(loop for line = (read-line s nil nil)
while line do (write-line line)))))
> So my error was in the (do ...) attempted loop.
DO is the all-purpose looping macro. Your code was actually creating
three variables("setq", "l" and "read-line" initialized to "s") and ended
the loop when the variable "print" became not null, returning the value
of "l". See http://www.lispworks.com/documentation/HyperSpec/Body/
m_do_do.htm#do