repl help system

For the Compleat Fan
Locked
starseed
Posts: 38
Joined: Thu Jul 27, 2006 8:45 pm

repl help system

Post by starseed »

I like to have an interpreter open, to check code snippets. Now, if the interpreter is already there, it would be nice to have an online help system ... here it is ;-)

Code: Select all

(define-macro (def)
   "Creates a lambda expression, while checking for doc-strings"
   (let  ((__def_func (args))
           (__def_help ""))
      (dolist (val (rest (__def_func 0)))
         (if (string? val) 
            (set '__def_help (append __def_help val)))
         (if (symbol? val)
            (set '__def_help (append __def_help "\n   " (string val) "\t - "))))
      (nth-set (__def_func 0) (clean string? (__def_func 0)))
      (set '__def_help (append (string (nth 0 __def_func)) "\n" __def_help))
      (if (string? (nth 1 __def_func))
         (begin 
            (set '__def_help (append __def_help "\n" (nth 1 __def_func)))
            (pop __def_func 1)))
      (push __def_help __def_func 1)
      (push 'define __def_func)
      (eval __def_func)
   )
)

(def (help "get quick help on function" 
      on-func "function you want help for") 
   {displays the doc-string of a function
   if on-func is a string, it searches all symbols for occurrence of this string
   if on-func is nil, return a list of all lambda, macro-lambda and primitives}
   (if 
      (nil? on-func)
         (filter (lambda (x) (or (lambda? (eval x))(macro? (eval x))(primitive? (eval x)))) (symbols))
      (string? on-func)
         (filter (lambda (x) (find on-func (string x))) (symbols))
      (lambda? on-func) 
         (if (string? (nth 1 on-func))
            (begin 
               (println (nth 1 on-func)) 
               '-)
            'not-documented)
      'not-a-lambda-expression
   )
)
Usage:
def - see 'help definition
help -

Code: Select all

> (help help)
(help on-func)
get quick help on function
   on-func	 - function you want help for
displays the doc-string of a function
   if on-func is a string, it searches all symbols for occurrence of this string
   if on-func is nil, return a list of all lambda, macro-lambda and primitives
-
> (help "xml")
(xml-error xml-parse xml-type-tags)
And again, comments are appreciated.


Ingo

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

First comment - thanks!

Second comment - you're not really a newbie ! ;-) I'm a newbie, so you can't be ...!

Third comment - Your suggestion made me wonder is there a good way of doing newLISP code? I know there's a Lisp way (probably a One True Lisp Way eg http://dept-info.labri.u-bordeaux.fr/~s ... ation.html), but I wonder how many of the current newLISP users use a similar methodology.

I was using semicolons but my attempts at formatting code using (load) always strip them out, so I've been tempted to switch to strings...

Keep up the great work - I'll understand it eventually...!

starseed
Posts: 38
Joined: Thu Jul 27, 2006 8:45 pm

Post by starseed »

1) You're welcome! ;-)
2) OK, I cheated a little bit. I've done some programming in Rebol, which has lispy roots. But it does away with all these parens - which now are my main problem ...
3) See above ... I sometimes need the parens on their lines, to be able to read it. But maybe I'll learn with time.
4) The main advantage of semicolons is that they can be optimized away while loading (hey, it's a comment, no need to keep it around). The main advantage of strings is, that they stay in the code, and thus can be saved from a running system. On the other hand, they pose a speed penalty, but I don't know how big it is ...
I first wanted to search for doc-strings throughout the whole function body, but I realized that this is too complicated for me now.


Ingo

pjot
Posts: 733
Joined: Thu Feb 26, 2004 10:19 pm
Location: The Hague, The Netherlands
Contact:

Post by pjot »

Hi,

There is also an interesting idea about defining help for newLISP in this topic:

http://www.alh.net/newlisp/phpbb/viewtopic.php?t=881

I have put this in my VIM macro's for newLISP, so within VIM I can always get info on a command (thanks to Lutz and Cormullion).
I've done some programming in Rebol, which has lispy roots.
You should meet newdep, he is a Rebol guy also ;-)

Peter

HPW
Posts: 1390
Joined: Thu Sep 26, 2002 9:15 am
Location: Germany
Contact:

Post by HPW »

In Ultraedit I have defined a tool/button:

Code: Select all

"C:\Programme\Internet Explorer\IEXPLORE.EXE" "C:\Programme\newlisp\newlisp_manual.html#%sel%"
to get context help like in newLISP-TK.
Hans-Peter

frontera000
Posts: 72
Joined: Sun Jun 11, 2006 8:02 pm
Location: berkeley, california
Contact:

a modification

Post by frontera000 »

Thanks. This is great!

I noticed if you do (help something-bogus) it will print list of symbols because
something-bogus will evaluate to nil.

Also (help xml-error) or (help 'xml-error) will print not-a-lambda expression.

I wrote this:
(def (help2 "get quick help on function v.2")
{displays the doc-string of a function
if argument provided is a string, it searches all symbols for occurrence of this string
if no argument is provided return a list of all lambda, macro-lambda and primitives
if argument provided is a primitive, it tells you that it is}
(let (on-func (args 0))
(if
(empty? (args))
(filter (lambda (x) (or (lambda? (eval x))(macro? (eval x))(primitive? (eval x)))) (symbols))
(primitive? (eval on-func))
(println (format "%s is a built-in primitive" (string on-func)))
(string? on-func)
(filter (lambda (x) (find on-func (string x))) (symbols))
(lambda? on-func)
(if (string? (nth 1 on-func))
(begin
(println (nth 1 on-func))
'-)
'not-documented)
'not-a-lambda-expression)))
which will do:
> (help2 something-bogus)
not-a-lambda-expression
> (help2 xml-error)
xml-error <41B383> is a built-in primitiv
"xml-error <41B383> is a built-in primiti
> (help2 'xml-error)
xml-error is a built-in primitive
"xml-error is a built-in primitive"
>
I also wrote something that will parse the HTML Documentation for newLISP and fetch documentation for built-in functions. But it looks ugly with HTML stuff, even when HTML tags are stripped. I am still thinking how to get that done. Perhaps there is a better way. Like Common LISP Hyperspec way.

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

also wrote something that will parse the HTML Documentation for newLISP and fetch documentation for built-in functions. But it looks ugly with HTML stuff, even when HTML tags are stripped.
Here is the perfect HTML cleaner on UNIX (and you also can get lynx for the PC):

Code: Select all

(define (html2text url)
   (exec "lynx -dump  > /tmp/text-file" (get-url url))
   (read-file "/tmp/text-file"))
As a help facitlity when in the newLISP console you can use:

Code: Select all

(define-macro (help func)
  (if (primitive? (eval func))
    (!  (format "lynx /usr/share/newlisp/doc/newlisp_manual.html#%s" (name func)))
    (format "%s is not a built-in function" (name func))))
After quitting out of Lynx, you are back in the newLISP console.

I wonder if that function could be somehow integrated into the newLISP EMACS facility. OSs which have EMACS tend to have lynx too. For the Mac there is "sudo port install lynx", when you have Darwin port tools installed.

Lutz

ps: the last function should be enhanced to translate the question mark '?' into 'p' for help on predicate keywords ending in '?'

- I just realize, an improved help function is already in the file: init.lsp.example in the newLISP source distribution.

starseed
Posts: 38
Joined: Thu Jul 27, 2006 8:45 pm

Re: a modification

Post by starseed »

Actually, all displayed behaviour has been by design ... maybe based on just being lazy ;-)

I'll have a look into your changes - and then it would be nice to integrate both html-help, and online quickhelp.

Regards,

Ingo ;-)

frontera000
Posts: 72
Joined: Sun Jun 11, 2006 8:02 pm
Location: berkeley, california
Contact:

apropos and describe

Post by frontera000 »

I wrote something similar to online help available in Common LISP. apropos will list out built-in functions that contain a string provided as an argument. describe will print out the manual page for the function and return the string containing the printed documentation.

(set '_manual-location "c:\\newlisp_manual.html")
(set '_manual-content "")

(define (apropos function-name-string context-name )
(if (nil? context-name) (setq context-name MAIN))
(if (context? context-name)
(filter (lambda (x) (find function-name-string (string x))) (symbols context-name))))

(define-macro (describe function-name-string)
(set '_str "")
(if (apropos function-name-string MAIN)
(begin
(if (= _manual-content "")
(set '_manual-content (read-file _manual-location)))
(set '_where (find (append "<a name=\"" function-name-string "\"") _manual-content 1))
(if (nil? _where)
(format "no entry for <s> in the manual" function-name-string)
(begin
(set '_end (find "<a>") ; from Peter's code
(replace "<" _str "<replace>")
(for (a 33 255)
(replace (append "&#" (string a) ";") _str (char a))
(replace (append "&#0" (string a) ";") _str (char a))
(replace (append "&#" (string a) ";") _str (char a)))
(replace "(<[^>]*>)" _str " " 1)
(println (format "%s" _str)))
(println "No such entry exists in the newLISP manual.")))
I tried to make 'describe' be easy to read, by stripping out HTML tags but I don't know if it is sufficiently readable. It is for me.

Hope this is useful.

frontera000
Posts: 72
Joined: Sun Jun 11, 2006 8:02 pm
Location: berkeley, california
Contact:

Post by frontera000 »

Before someone points it out... I know "describe" does something different in Common LISP. The equivalent would be "documentation". But I find that it is easier for me to remember and type "describe".

frontera000
Posts: 72
Joined: Sun Jun 11, 2006 8:02 pm
Location: berkeley, california
Contact:

bug fix

Post by frontera000 »

Already I noticed a problem. It seems that newLISP Documentation tag for predicates (context? nil? etc.) which end with "?" are tagged with "p" instead of "?". So I had to change the code a bit:

Code: Select all

(set '_manual-location "c:\\newlisp_manual.html")
(set '_manual-content "")

(define (apropos function-name-string context-name )
  (if (nil? context-name) (setq context-name MAIN))
  (if (context? context-name)
      (filter (lambda (x) (find function-name-string (string x))) (symbols context-name))))

(define-macro (describe function-name-string)
  (set '_str "")
  (if (apropos function-name-string MAIN)
      (begin 
	(if (= _manual-content "")
	    (set '_manual-content (read-file _manual-location)))
	(if (ends-with function-name-string "?")
	    (set 'function-name-string (append (chop function-name-string) "p")))
	(set '_where (find (append "<a name=\"" function-name-string "\"") _manual-content 1))
	(if (nil? _where)
	    (format "no entry for <s> in the manual" function-name-string)
	    (begin
	      (set '_end (find "<a>")    ; from Peter's code
	(replace "<" _str "<replace>")
	(for (a 33 255)
	     (replace (append "&#" (string a) ";") _str (char a))
	     (replace (append "&#0" (string a) ";") _str (char a))
	     (replace (append "&#" (string a) ";") _str (char a)))	
	(replace "(<[^>]*>)" _str " " 1)
	(println (format "%s" _str)))
      (println "No such entry exists in the newLISP manual.")))

Tim Johnson
Posts: 253
Joined: Thu Oct 07, 2004 7:21 pm
Location: Palmer Alaska USA

Post by Tim Johnson »

I've been coding in rebol for 9 years now.
I use a user-defined function (Also called 'def):
That generates a subroutine where all defined 'words
are of scope local to the subroutine. It would be great if
something like that were available in newlisp, but I suspect that
would be impossible with newlisp.
tim

Locked