Some Boolean Helpers

Started by Jeremy Dunn, May 31, 2006, 08:22:46 PM

Previous topic - Next topic

Jeremy Dunn

I think you all will find these interesting. First the code:


;;Negate a boolean function
;;Write (not (= x y)) as (n = x y)
(define-macro (n)
  (not (eval-string
         (join (list "("
                     (join (map name (map sym (args))) " ")
                     ")"
               ))
  ))
)


;;Convert a boolean to an if statement
;;Write (if (= x 3) a b) as (i = x 3 a b)
(define-macro (i)
  (setq vars   (map name (map sym (args))))
  (setq L      (length vars))
  (setq a-part (vars (- L 2)))
  (setq b-part (last vars))
  (setq test   (join (0 (- L 2) vars) " ")
        test   (join (list "(" test ")"))
  )
  (eval-string
    (join (list "(if " test " " a-part " " b-part ")")))
)


;;Convert a boolean to an if statement
;;Write (if (not (= x 3)) a b) as (ni = x 3 a b)
(define-macro (ni)
  (setq vars   (map name (map sym (args))))
  (setq L      (length vars))
  (setq a-part (vars (- L 2)))
  (setq b-part (last vars))
  (setq test   (join (0 (- L 2) vars) " ")
        test   (join (list "(not (" test "))"))
  )
  (eval-string
    (join (list "(if " test " " a-part " " b-part ")")))
)


The n, i and ni functions all provide convenient simplifications of common statements with booleans as the explanations show. Lots of parentheses can be got rid of with these handy tools. However, I'm looking for some help here. Right now the functions handle built-in boolean functions OK but don't seem to handle user-defined ones. I'm also uncertain whether they will break under other conditions that I haven't provided for. I'm hoping some of the more adept ones here can show me a better way of doing this to make the functions more robust.

Lutz

#1
All the string conversions with subsequent 'eval-string' are not necessary. For example your first macro is the same as saying the much shorter:



(define-macro (n) (not (eval (args))))


and then why not just write:



(not (= x y)) ; instead of (n = x y)


Lutz

Jeremy Dunn

#2
Thanks for the help, I didn't realize I could write it that way.



I know (n = x y) seems trivial but it does get rid of a set of parentheses. The ni function would get rid of 4 parentheses and these situations occur all the time. Perhaps no one is interested except me. Anyone else?

cormullion

#3
Quote from: "Jeremy Dunn"... but it does get rid of a set of parentheses. The ni function would get rid of 4 parentheses and these situations occur all the time. Perhaps no one is interested except me. Anyone else?


I know what you mean. My initial fear of the parenthesis 'issue' has quickly turned into a liking - indeed reliance - on them. Using a decent editor, of course. What I like about the parentheses is that I can quickly select the elements of thought, and cut or copy them. Imagine if, when writing English, you could quickly and easily say "select this subclause" or "remove this sentence". So now I really like using them - they clarify the structure and facilitate editing - and find I don't want to get rid of them anymore...



- my (* (/ euro 100) 2) ...

m i c h a e l

#4
Quote from: "Jeremy"Perhaps no one is interested except me. Anyone else?


newLISP is so much like a pile of clay (in a good way ;-), waiting to be formed into whatever the programming potter wishes it to be, that it's better for it to remain faithful to the simple ideas that originated in LISP and stay a pile of clay. Parentheses and all :-)



So many kinds of pots and bowls and plates and mugs can be made from the same thing: newLISP. If extending the language to allow for n, i, and ni with macros makes you happy, then go ahead, use the macros and be happy. But, watch out for Hans-Peter. He'll be on you about that non-standard code, and how it will be confusing to others in the group ;-)



One thing I've learned from studying a few programming languages is that you're always better off accepting the language's idioms and orientations. Soon, you find you are as comfortable with the languages new way as you were with whatever way you were familiar with before. I think this is what the Pragmatic Programmers meant with their advice to "Learn at least one new [programming] language every year. Different languages solve the same problems in different ways. By learning several different approaches, you can help broaden your thinking and avoid getting stuck in a rut." Maybe that should have been "learn a new programming paradigm every year" ;-)





m i c h a e l



P.S.
Quote from: "cormullion"- my (* (/ euro 100) 2) ...


Funny :-)

Lutz

#5
Quote
By learning several different approaches, you can help broaden your thinking and avoid getting stuck in a rut." Maybe that should have been "learn a new programming paradigm every year" ;-)


well put



Lutz



ps: improved cormullion quote for US readers:


Quote
- my (* (/ euro 128.55) 2) ...




:)

HPW

#6
QuoteMy initial fear of the parenthesis 'issue' has quickly turned into a liking - indeed reliance - on them. Using a decent editor, of course.


Not a first view love, but then a deep one. ;-)


QuoteBut, watch out for Hans-Peter. He'll be on you about that non-standard code, and how it will be confusing to others in the group ;-)


I am really not on someone who share our liking of newLISP and get a active member of this comunity. I had only once a problem, where code gets posted which contains self-defined (not shown) macro's.

;-)


QuotenewLISP is so much like a pile of clay (in a good way ;-), waiting to be formed into whatever the programming potter wishes it to be, that it's better for it to remain faithful to the simple ideas that originated in LISP and stay a pile of clay. Parentheses and all :-)


I like that quote. It is similar to the philosophie found in Paul Grahams essays, where he talks about 'bottom-up design-- changing the language to suit the problem'.



http://www.paulgraham.com/progbot.html">http://www.paulgraham.com/progbot.html



So on every new project/problem, newLISP behave like a chameleon. It changed to a new language (of the Lisp-family) for solving that problem.
Hans-Peter

m i c h a e l

#7
Quote from: "Hans-Peter"newLISP behave like a chameleon.


I like that simile. The language taking on the colors of the environment in which it finds itself. Blending in. Belonging. Thing of it is though, the dragonfly may not want to share the spotlight with a lizard ;-) Although, with the dragonfly's ability to project a false image of itself, they may not be so different, after all.





m i c h a e l

Jeremy Dunn

#8
Thanks for the responses everyone.



I guess I was thinking of the functions being kind of like implicit indexing. One might argue that we should all be clear and use nth or slice instead but the minimalism is fun. Of course this is the strength of LISP, we can make it into what suits our fancy. Here's a little better version of the functions for those that want to play


;;Negate a boolean function
;;Write (not (= x y)) as (n = x y)
(define-macro (n)(not (eval (args))))

;;Convert a boolean to an if statement
;;Write (if (= x 3) a b) as (i = x 3 a b)
(define-macro (i)
  (setq L (length (args)))
  (if (eval (0 (- L 2)(args)))
      (eval (nth -2 (args)))
      (eval (last (args)))
  ))

;;Convert a boolean to an if/not statement
;;Write (if (not (= x 3)) a b) as (ni = x 3 a b)
(define-macro (ni)
  (setq L (length (args)))
  (if (not (eval (0 (- L 2)(args))))
      (eval (nth -2 (args)))
      (eval (last (args)))
  ))