Using (sin cos 0.5) instead of (sin (cos 0.5)) in Newlisp.




; Recently, Jeremy Dunn on Newlisp forum expressed desire to use
; the single argument functions in Newlisp in following fashion:
;
;     (sin cos 0.5) = (sin (cos 0.5))
;     
; The motivation is well know in Lisp world: avoidance of parentheses.
; I believe that regularity of the Lisp syntax should be preserved
; and that it is better to be consistent, although more verbose.
;
; However, the problem is interesting.
;
; At least two works are already done in Newlisp in that dyrection. Cyril
; Slobin described make-pass macro:
;
;         http://slobin.livejournal.com/148287.html
;
; (define-macro (make-pass)
;   (doargs (arg)
;     (letex ((Old arg)
;             (New (sym (append (string arg) "&"))))
;       (define-macro (New)
;         (Old (eval (args)))))))
;
; (make-pass catch not print)
;
; Here is how it works:
;
; (catch& while (read-line)
;   (setq line (current-line))
;   (if (not& empty? line)
;     (print& format "%s\n" line)
;     (throw 'empty)))
;
; My construct for composition of arbitrary functions
; or fexprs should be mentioned as well.
;
;   http://kazimirmajorinc.blogspot.com/2010/02/composition-of-functions-or-macros.html
;
; Its syntax should be:
;
; ((compose sin cos) 0.5)
;
; Needless to say, compose is "in the spirit" of the Lisp,
; but it is syntactically heavier than original (sin (cos 0.5)).
; And Jeremy didn't liked even Cyril's (sin& cos 5).
;
; So, I adapted Cyril's idea to work without that extra &, but
; then it had to work both like sin& and original sin.

(println (sin 3))
(println (sin (cos 4)))
(println (sin (cos (sin 5))))

; 0.1411200081
; -0.6080830096
; 0.5433319155

(define-macro (make-pass-adapted)
  (doargs (arg)
     (constant arg
        (letex((arg (eval arg)))
           (lambda-macro()
              (arg (eval (if (> (length (args)) 1)
                             (args)
                             (first (args))))))))))
        
(make-pass-adapted sin cos)

(println (sin (+ (cos 0) (cos 0) (cos 0))))
(println (sin cos 4))
(println (sin cos sin (+ 2 3)))

; 0.1411200081
; -0.6080830096
; 0.5433319155

; I'll test it whether it works with Cyril's example.

 (make-pass-adapted catch not print)   
 
 (catch while (read-line)
   (setq line (current-line))
   
   (if (not empty? line)
     (print format "%s\n" line)
     (throw 'empty)))
     
; It's really easy, so I had doubt whether it is important enough
; to blog about that, lets say, sinful sin. However, I noticed
; that it is interesting example of the function that is replaced
; with FEXPR.


No comments:

Post a Comment