Making true and nil functions...

Started by itistoday, September 10, 2008, 10:12:20 AM

Previous topic - Next topic

itistoday

I don't know scheme very well, but I saw something in some scheme code the other day that I've wished before was in newlisp:


((> i n) (newline))

Wouldn't it be cool if you could do that?  So instead of doing:


(if (> 1 0) (println "it is!"))

You could just do:


((> 1 0) (println "it is!"))

You could even have the syntax allow an entire body of statements to be evaluated, e.g.:



function: (true <body>) => evaluates <body>

function: (nil <body>) => does NOT evaluate <body>



Or would this break too many things..?
Get your Objective newLISP groove on.

Lutz

#1
Since 9.4.8 you already can do this, but have to start newlisp with the -x option:


$ newlisp -x
newLISP v.9.4.8 on OSX IPv4 UTF-8, execute 'newlisp -h' for more info.

> (true 'y 'n)
y
> (nil 'y 'n)
n
>


Be careful as this mode can lead to hard to detect errors ;). If you use the newLISP-GS editor a lot you can put:



(set 'currentExtension "-x")



into .newlisp-edit.conf



this will make the monitor shell come up in the same -x mode.

cormullion

#2
Hmmm! What's this mode doing?

itistoday

#3
Neat!  This really is a secret feature, it's not mentioned in the release notes nor in the man page.  I echo cormullion's question.
Get your Objective newLISP groove on.

newBert

#4
Quote from: "Lutz"Since 9.4.8 you already can do this, but have to start newlisp with the -x option:


$ newlisp -x
newLISP v.9.4.8 on OSX IPv4 UTF-8, execute 'newlisp -h' for more info.

> (true 'y 'n)
y
> (nil 'y 'n)
n
>


Personally, I find that less legible (or readable) than :

newLISP v.9.4.8 on Win32 IPv4, execute 'newlisp -h' for more info.
> (if true 'y 'n)
y
> (if nil 'y 'n)
n
>


but newLisp is quite flexible to give us the choice and adapts to our former habits.

:o)
<r><I>>Bertrand<e></e></I> − <COLOR color=\"#808080\">><B>newLISP<e></e></B> v.10.7.6 64-bit <B>>on Linux<e></e></B> (<I>>Linux Mint 20.1<e></e></I>)<e></e></COLOR></r>

Lutz

#5
QuotePersonally, I find that less legible (or readable) ...


I completely agree. The reason to built this in as an option was to explore the possibilities to write a Lisp with only lambda and less than the 5 functions stated by McCarthy, which are:  =, atom?, cond, cons, first, rest, quote (different uppercase names in the original texts).



This doesn't have any practical implications, just a nice brain-teaser exercise. There are no intentions to introduce an implicit if for real, it leads to hard to detect error conditions.



If we allow the implicit if and also use the newLISP 'args' function we can do with just: =, atom?, cons, quote and args, bringing it down to 5 functions from previously 7. 'args' can be used to define at least: list, first, rest. Instead of 'cond' we would use nested implicit 'if's.



To write an 'eval' function in newLISP (that would be writing Lisp in Lisp), we would also need: 'empty?' , 'and', 'not', 'assoc', 'append', 'list', 'pair'. But all these can be built using the previous 5.  Perhaps even 'cons' could be expressed using the other 4 :). The function 'args' would play an important role here ... Or perhaps somebody come up with an entirely different algorithm ...



In case you have nothing better to do, think about it ;-), here is a start:


(define (EMPTY? x)
(= x '()))

(define (OR x y)
((= nil x) ((= nil y) nil true) true))

(define (NOT x)
((= nil x) true nil))

(define (AND x y)
((NOT (= nil x)) ((NOT (= nil y)) true nil) nil))

(define (LIST) (args))

(define (FIRST) ((args 0) 0))

(define (REST) (1 (args 0)))

...


These and CONS (cons) are enough to define PAIR (make a list of pairs from two lists), APPEND and ASSOC. Having all those and QUOTE (quote) and ATOM? (atom?) you can define (EVAL x envList), where x is any s-expression (symbol or list) and envList is an association list describing you variable bindings. As there is no 'set', variable bindings must be described in an association list. For LABEL we simply use 'define' as in:



(define EVAL (lambda (x a) ...))



Here a little help from the master McCarthy himself:

http://www.newlisp.org/notthewholetruth.pdf">http://www.newlisp.org/notthewholetruth.pdf



Translated to Common Lisp by Paul Graham:

http://lib.store.yahoo.net/lib/paulgraham/jmc.ps">http://lib.store.yahoo.net/lib/paulgraham/jmc.ps



Or for the mathematically inclined:

http://www-formal.stanford.edu/jmc/recursive.pdf">http://www-formal.stanford.edu/jmc/recursive.pdf

DrDave

#6
How about using OR in the definition of AND


(define (AND x y)
           (NOT (OR (= nil x) (= nil y))))

It seems to me easier to see that if at least one of the arguments is false, AND returns false.



another alternative:
(define (AND x y)
         ;; Returns FALSE if at leaset one argument is FALSE.
           (NOT (OR (NOT x) (NOT y))))

But I think the one above is clearer.



But if for some odd reason you are trying to implement implicit IFs, here is another variant


(define (AND x y)
          ((= nil x) nil ((= nil y) nil true)))


By the way Lutz, how did you get the idea to use NOT and come up with  that convoluted version? That seems NOT to be the way you normally work. LOL



And here is a hybrid
(define (AND x y)
           ((= nil x) nil (not (= nil y))))

And just for fun, now about some ANTI- functions...
(define (ANTI-AND x y)
         ;; Returns FALSE if at leaset one argument is TRUE.
           (NOT (OR (true? x) (true? y))))


Like anti-matter and matter meeting and being annihilated, ANDing the ANTI-AND and regular AND always returns FALSE. Similarly, anti-matter exists peacefully with other anti-matter, as does matter with matter. So ORing ANTI-AND with AND results in peaceful existence (returns TRUE) when both arguments are the same, and results in annihilation (returns FALSE) when the two arguments are different.
...it is better to first strive for clarity and correctness and to make programs efficient only if really needed.

\"Getting Started with Erlang\"  version 5.6.2

xytroxon

#7
My favorite group, "The Boole-atles", sang it best: "All you need is NAND" ;)



You can construct any boolean function using only NAND and DeMorgan's theorems...



http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_2/CH02-3.html">//http://www.oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_2/CH02-3.html


QuoteAlthough there is a tenuous relationship between boolean functions and boolean expressions in programming languages like C or Pascal it is fair to wonder why we're spending so much time on this material. However the relationship between boolean logic and computer systems is much stronger. There is a one-to-one relationship between boolean functions and electronic circuits. Electrical engineers who design CPUs and other computer related circuits need to be intimately familiar with this stuff. Even if you never intend to design your own electronic circuits understanding this relationship is important if you want to make the most of any computer system.



-------



Of course there is one other reason for studying boolean functions even if you never intend to write software intended for an embedded system or write software that manipulates real-world devices. Many high level languages process boolean expressions (e.g. those expressions that control an if statement or while loop). By applying transformations like DeMorgan's theorems or a mapping optimization it is often possible to improve the performance of high level language code. Therefore studying boolean functions is important even if you never intend to design an electronic circuit. It can help you write better code in a traditional programming language.


-- xytroxon
\"Many computers can print only capital letters, so we shall not use lowercase letters.\"

-- Let\'s Talk Lisp (c) 1976