Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - eddier

#1
newLISP in the real world / calendar program
June 11, 2009, 10:24:09 AM
Hello Lutz.



I once wrote a web calendar program an posted it on newlisp. I figured you had updated it so that it would run with newer versions of newlisp. I was wondering if you have an updated version? I need to modify it so that it will run on one of our httpd servers on a specified port.



Eddie
#2
newLISP newS / Where is 8.8
January 11, 2006, 01:18:37 PM
Lutz,



I see "next release version 8.8 February 10th, 2006" on the main Web page but I see not the download?



Eddie
#3

(1 "ab") => "b"  ;Correct
(1 "a") => "a"  ;Incorrect
(rest "a") => ""


Eddie
#4
newLISP in the real world / roman numerals revisited
October 31, 2005, 12:41:25 PM
Lutz,



I've been trying to recode some of my recursive routines to iterative ones. The iterative versions aren't nearly as elegant. For example, recoding a recursive roman numeral conversion to an iterative version looks horrible (below). Looks even worse to maintain, but you're right, it runs significantly faster.



(define (->roman n)
    (let (s "" v '(100 50 40 10 9 5 4 1))
      (dotimes (i (length v))
        (while (>= n (v i))
          (setq s (append s ('("C" "L" "XL" "X" "IX" "V" "IV" "I") i))
                n (- n (v i)))))
      s))


Am I doning the right thing here? Or, should I be coding in a different way I'm not familiar with? (dotimes (while ick!



Eddie
#5
newLISP in the real world / format
June 22, 2005, 12:55:16 PM
Lutz,



I've found use on several occasions to have an optional list of variables or values in format.



For instance, suppose L = ("bob" "this" "that" 3 2 10 "a" 96 "----" 456). We could write

(println (format "%s,%d,%s,%dn" (select L 0 4 1 7)))


vs

(println (format "%s,%d,%s,%dn" (L 0) (L 4) (L 1) (L 7))))


Implicit indexing helps, but selecting from a list would be nicer.



Eddie
#6
newLISP in the real world / strange mapping
June 14, 2005, 10:18:31 AM
Suppose

(define data '((1 2) (2 3) (3 4)))
(println (map first data))

=>
(1,2,3)

Okydoky! That's what I expect. But,


(println (map 0 data))
=>
((1 2) (2 3) (3 4))

and


(println (map 1 data))
=>
((2) (3) (4))

Looks like (map n list) means appling (n sublist) instead of (sublist n).

Shouldn't this be the other way around? That
(map 0 data) => (1 2 3) and
(map 1 data) => (2 3 4)?



Eddie[/i]
#7
Anything else we might add? / indexing
March 24, 2005, 01:49:35 PM
I absolutely LOVE the implicit  indexing Lutz. Just one question, can we do something with rest in a similar manar?



Eddie
#8
newLISP newS / implicit indexing
March 18, 2005, 07:59:26 AM
Neat! I've not seen anything quite like this before. The first thing after a non-quoted list is not interpreted as a function.

> (setq a '((1 2) 3))
((1 2) 3)
> (a 1)
3
>


Thyping (a 1 2) is as easy to type as a[1][2] and maybe as easy to read?



Eddie
#9
newLISP newS / implicit indexing
March 18, 2005, 07:52:20 AM
Neat! I've not seen anything quite like this before. The first thing after a non-quoted list is not interpreted as a function.

> (setq a '((1 2) 3))
((1 2) 3)
> (a 1)
3
>


Thyping (a 1 2) is as easy to type as a[1][2] and maybe as easy to read?



Eddie
#10
newLISP in the real world / sorting
March 09, 2005, 01:16:09 PM
Lutz,



In a particular CGI program I am writing the following problem has come up.



I will have to write a sort based on a comparison function. For example, I need to ignore case of letters and I need to sort by a different element of lists of lists as in

(sort (("12" "Bb") ("32" "ab")) f)

where f is a function to compare the 2nd elements without case.

I was able to

(define (sort-by L col)
  (map (fn (y) (swap 0 col y))
       (sort
(map (fn (x) (swap 0 col x))
    L))))

but I still have the problem of a case sensitive sort.  If I code a sort myself in newlisp, I have the problem of setting the stack. Because lists may get rather long, how do I force a cgi to make newlisp change it's stack size?

Maybe I should write a c function store it in a library and use it?



Eddie
#11
newLISP in the real world / catch is broken
January 20, 2005, 08:27:16 AM

(define (f x y)
 (if (= 0 x)
  (throw "x can't be zero")
  (+ x y)))

> (catch (f 0 2) 'result)
true
>result
"x can't be zero"
> (catch (f 1 1) 'result)
true
> result
2


catch is always returning true.



Eddie
#12
newLISP in the real world / max
December 16, 2004, 09:21:53 AM
Would be nice if max and min worked with strings or is this a bad idea?



(max "a" "A" "B" "b" "C") => "b"



Eddie
#13
Whither newLISP? / expand and define-macro
December 09, 2004, 07:09:12 AM
Lutz,



It would be nice to have expand work on stuff like

(setq a 'r)
(expand (a:a b)  'a ) => (r:r b)

instead of having to do string manipulation like below

(define-macro (def-mac _dm _body)
 (let (_s (string _dm))
  (eval-string
   (format "(context '%s) (define-macro (%s:%s) %s) (context 'MAIN)"
           _s
           _s
           _s
           (string (eval _body)))))


What I would like is to create a macro definition that performs

(context 'my-setq)

(define-macro (my-setq:my-setq x y) (set x (eval y)))  

(context MAIN)

by just typing

(def-mac (my-setq x y) (set x (eval y)))

although I haven't quite figured out how to do the parameters yet.

Note this is almost static scoping for macros  (the variables within the context remain after the macro call). If context variables where deleted on leaving the call we would have static scoping. I wonder if contexts could be used to form a contiunation? Is it possible to make define-macro statically scoped in newLISP?



Eddie
#14
So, what can you actually DO with newLISP? / cgi and html
December 02, 2004, 01:31:27 PM
I thought I had posted this, but I guess I didn't. And if I did, this is an update. Anyway a convient cgi.lsp for cgi.



(context 'CGI)

;; by Eddie Rucker
;; allows easyly interchangable HTML and newLISP code
;; version 0.6 (Dec 2, 2004) -- made code a bit better, turned around the "="
;; version 0.5 (Nov 29, 2004) -- fixed symbol evaluation
;; NO WARRANTY OF ANY KIND
;; credit for the idea goes to Tim Bradshaw although mine is a bit different

;; example
;;(load "cgi.lsp")
;; (:CGI
;;  (:html
;;   (:head
;;    (:title "fred")
;;   (:body
;;    (:form action="test.lsp" method="get"
;;     (:h1 style="text-align:center" "fred")
;;     (:table width="100%"
;;      (:tr
;;       (:td "First Name:")
;;       (:td (:input type="text" size="15"))
;;      (:tr
;;       (:td "Last Name:")
;;       (:td (:input type="text" size="15")))))))))
;;(exit)

;; parse url
(map (fn ($x$)
(let ($L$ (parse $x$ "="))
  (set (symbol (first $L$)) (last $L$))))
     (parse (replace "%([+0-9A-F]{2})"
    (or (read-line) (env "QUERY_STRING") "")
    (if (= $1 "+") " " (char (integer (append "0x" $1)))) 0)
   "[&;]" 0))

(context 'MAIN)

;; <tag>...</tag> constructs -- add to the list as needed
(dolist ($x$ '("html" "head" "body" "form" "style" "title" "div" "table" "tr"
      "th" "td" "a" "h1" "h2" "h3" "h4" "h5" "h6" "sub" "sup" "p" "b"
      "i" "u" "center" "option" "select" "ul" "ol" "dl" "li" "dt"
      "dd" "caption" "textarea"))
  (eval-string
   (format "(define-macro (:%s) (format "<%s%%s</%s>" (<tag> (args))))"
  $x$ $x$ $x$)))

;; <tag /> constructs -- add to the list as needed
(dolist ($x$ '("br" "hr" "img" "input"))
  (eval-string
   (format "(define-macro (:%s) (format "<%s%%s" (<tag /> (args))))"
  $x$ $x$)))


(define (<tag/> $L$)
  (let ($w$ (first $L$) $rl$ (rest (rest $L$)))
    (if
(empty? $L$)  
 " />n"
        (and (symbol? $w$) (= "=" (last (string $w$))))
 (format " %s="%s"%s"
 (chop (string $w$))
 (eval (nth 1 $L$))
 (<tag/> $rl$))) ))

(define (<tag> $L$)
  (let ($w$ (first $L$) $rl$ (rest (rest $L$)))
    (if
(empty? $L$)
 ">n"
(and (symbol? $w$) (= "=" (last (string $w$))))
 (format " %s="%s"%s"
 (chop (string $w$))
 (eval (nth 1 $L$))
 (<tag> $rl$))
(append ">n" (to</tag> $L$))) ))

(define (to</tag> $L$)
  (let ($w$ (first $L$))
    (if (empty? $L$)
""
      (format "%sn%s"  (eval $w$)  (to</tag> (rest $L$))))))

(define (:CGI $w$)
  (print (format "Content-type: text/htmlnn%s" $w$)))

For any CGIers out there.



Eddie
#15
newLISP in the real world / html
November 12, 2004, 01:09:32 PM
Kind of a macro within macro within ... thingy that really helps with html code.



(define (<page> %w)
  (replace "`(.+?)`" %w (string (eval-string $1)) 516)
  (if (> $0 0) (<page> %w) %w))

...

(let (isfred true val "fred")
  (print [text]Content-type: text/html

<html>
<body>
<p>`(if test
              "Hello `val`!"
              "You are not `val`!")`</p>
</body>
</html>[/text]))


Three things to notice,

  1. Lutz was right about using 512 in replace when nesting. Notice `val` nested within the `(if ...)`

  2. I added 4 because I needed to match across newlines.

  3. I didn't see a post-test loop for newlisp in reference manual. I was fooled by (until ) until I noticed that it meant (while (not ...  Still a pre-test loop. The recursive version of (<page> %w) would be a one liner using something like

(define (<page> %w)
  (repeat (> $0 0) (replace "`(.+?)`" %w (string (eval-string $1)) 516)))


Would a post-test loop construct be usefull for anyone else? I try to stay functional for the most part, but here, an imperative construct seems to be most natural.



What do you think Lutz?



Eddie
#16
newLISP in the real world / [text][/text]
November 02, 2004, 09:42:48 AM
What would really be wonderful for us cgi tinkerers would be to evaluate variables and functions within the [text] [/text] tags like



(set 'title "Today")

(pr
[text]Content-type: text/html

<html>
<head>
  <title>#{title}</title>
</head>
<body>
  <p>Today is #{(now)}</p>
</body>
</html>
[/text])

I have done some other stuff like put (const (global '<html>) "<html>n") etc. in the init.lsp and it helps like the following
[code]
(pr cgi-header
  <html>
  <body>
  ...
  </body>
  </html>
)



But I think being able to evaluate stuff in text tags would be much better. Is it possible?



Eddie
#17
newLISP in the real world / let
October 29, 2004, 06:24:10 PM
Would it be difficult to fix let so that I could reference other local variables like

(let (x (car L) y (car x) ...)

This would reduce the amount of nested lets like

(let (x (car L))
  (let (y (car x))
  ...


What do you think about this one?



Eddie
#18
newLISP in the real world / rational library
September 22, 2004, 02:32:10 PM
I'm having trouble with some macros.



(context 'Q)

;; '(2) means 2/1, '(1 2) means 1/2, and (2 2 3) means 2 2/3
;; all functions below will work with the above types
;; (Q:neg '(1 2) => (-1 2)
;; (Q:reciprical '(-2 3) => (-3 2)
;; (Q:+ '(1 2) '(1 3)) => (5 6)
;; (Q:- '(1 2) '(1 3)) => (1 6)
;; (Q:* '(1 2) '(1 3)) => (1 6)
;; (Q:/ '(1 2) '(1 3)) => (3 2)


(define (gcd_ a b)
;; used to reduce fractions
  (let (r (% b a)) (if (= r 0) a (gcd_ r a))))

(define (frac-form a b)
;; reduce and fix negatives so that -a/-b => a/b, a/-b => -a/b
(if
(= a 0)
'(0 1)
(= b 0)
(throw "rational-number-error")
(let (dd (gcd_ a b))
(let (a (/ a dd) b (/ b dd))
(if
(and (< a 0) (< b 0))
(map abs (list a b))
(and (>= a 0) (< b 0))
(list (- 0 a) (abs b))
(list a b))))))

(define (improper L)
;; convert a -> a/1 and  a b/c -> (c*a+b)/c
(map set '(n d)
 (if
(= (length L) 1)
(list (first L) 1)
(= (length L) 2)
L
(= (length L) 3)
(list (+ (nth 1 L)  (* (first L) (last L)))  (last L))))
(frac-form n d))

(define (neg A)
(map set '(n d) (improper A))
(frac-form (- 0 n) d))

(define (add_q A B)
(map set '(n0 d0 n1 d1) (append (improper A) (improper B)))
  (let (n (+ (* n0 d1) (* n1 d0))  d (* d0 d1))
(if (frac-form n d))))

(define (sub_q A B)
(add_q A (neg B)))

(define (mul_q A B)
(map set '(n0 d0 n1 d1) (append (improper A) (improper B)))
(frac-form (* n0 n1) (* d0 d1)))

(define (reciprical A)
(frac-form (last A) (first A)))

(define (div_q A B)
(mul_q A (reciprical B)))

(define (->string A)
(if (= (last A) 1)
(string (first A))
(string (first A) "/" (last A))))

(constant 'Q:+ add_q)
(constant 'Q:- sub_q)
(constant 'Q:* mul_q)
(constant 'Q:/ div_q)

(context 'MAIN)


The functions work just fine until I add something like

(define-macro (qadd) (apply add_q (args) 2))


and then I get the error



list expected : (if (= (length Q:L) 1)

 (list (first Q:L) 1)

 (= (length Q:L) 2) Q:L

 (= (length Q:L) 3)

 (list (+ (nth 1 Q:L) (* (first Q:L) (last Q:L))) (last Q:L)))

called from user defined function improper


Why?



Eddie
#19
newLISP in the real world / gcd
September 22, 2004, 09:09:51 AM
There is an error in the documentation in the code snippets section under Tips and Tricks.


(gcd a b c ...)

gives the greatest common divisor of two or more integers. A common denominator is the


(lcm a b c ...)

or least common multiple of two or more integers. The (lcm a b c ...) function could be defined as



(define-macro (lcm)
  (/ (apply * (args) 2) (apply (gcd_ (args) 2)))


given the (gcd_ auxilary function.



Maybe I should have used the alternative name "gcf," greatest common factor instead of gcd.



Eddie
#20
newLISP in the real world / threads
September 15, 2004, 09:26:21 AM

(context 'DATA)
(setq t1 100 t2 100)

(context 'MAIN)
(define (thread-1 x)
  (while (!= x 0)
    (begin
     (sleep 100)
     (setq DATA:t1 x)
     (dec 'x))))

(define (thread-2 x)
  (while (!= x 0)
    (begin
     (sleep 100)
     (setq DATA:t2 x)
     (dec 'x))))

(define (observer)
  (println DATA:t1 "," DATA:t2)
  (setq i 40)
  (while (!= i 0)
    (println "thread-1 " DATA:t1 "nthread-2 " DATA:t2)
    (sleep 100)
    (dec 'i)))

(fork (observer))
(fork (thread-1 20))
(fork (thread-2 20))

(exit)


Three questions:

 1. Why doesn't fork 1 and fork 2 change DATA:t1 and DATA:t2 respectively?

 2. How do I communicate with a thread?

 3. Why do I have to hit "Enter" to get the main program to exit. This means CGIs with threads won't work.



Eddie