Nil is not the empty list? - scheme

I am learning Scheme and am using an online interpreter from repl.it. I am having some trouble understanding why this returns #f:
(eq? '() 'nil) ; ==> #f

In LISP 1.5 nil, 'nil, '() and () evaluates to nil. The reader translated () and nil into the same singleton empty list and it is self evaluating so that the quote is optional. nil is also the only false value and all other values are truthy. The very first Scheme implementation was hosted by a commercial Lisp compatible with 1.5 and much of the host were used transparently in the first Scheme. Common Lisp is a descendant of 1.5 and still works like this, but Scheme has had changes from report to report and these are the rules from R5RS and later:
The empty list is '(). It's quoted and evaluates to (). It is not self evaluating so () is invalid Scheme code. 'nil evalutes to nil which is a symbol and not the empty list. In Scheme the only false value is #f and thus the empty list is truthy.
In code:
'() ; ==> ()
'(1 . (2 . ()) ; ==> (1 2)
() ; ==> ERROR: Illegal empty application (not allowed)
(eq? '() 'nil) ; ==> #f (empty list and nil are different values)
(if '() #t #f) ; ==> #t (empty list is truthy)

Related

true and false null values in lisp vs scheme

I want to use the function in a scheme program im writing however im unsure ho to translate the T & Nil values within the function. Can nil essentially be written as '() in scheme?
(define (listword (lambda (word)
(cond
((isvowel (car word)) (novowel word))
(T (novowel word NIL))))))
To avoid confusion I'll take Common Lisp as an exemplar of a 'traditional' Lisp and call it 'Lisp' below, as opposed to Scheme: Scheme is also a Lisp of course but I want to have to type less.
Both Lisp and Scheme use the common convention that there is a single distinguished false object with everything else being true. In the construction of lists, both Lisp and Scheme also need to have a special distinguished 'empty list' element which is also unique. Lisp then chooses to pun, making the empty list and false be the same object: Scheme does not, and treats them as distinct. Additionally, Lisp provides a name for the empty list object, while Scheme does not, and Scheme also does not treat the empty list object as self-evaluating while Lisp does. Both languages provide a canonical true object as well, but again Lisp provides a name for it while Scheme doesn't. In both languages the true and false objects are self-evaluating.
So.
(Common) Lisp:
all objects are true except for the empty list, () -- (if () 1 2) evaluates to 2;
the empty list is self-evaluating -- (eq '() ()) is true;
the empty list is unique -- (eq () ()) and (eq () '()) are both true, as is (eq () (cdr (list 1))) for instance;
the empty list has a name, NIL -- (eq nil ()) & so on;
there is a canonical true object whose name is T and whose value is T;
while it is perhaps disputed, I think it is better to use NIL when you want to talk about false and () when you want to talk about the empty list.
Scheme:
all objects are true except for the special false object which is #f -- (if #f 1 2) evaluates to 2 while (if x 1 2) evaluates to 1 for x having any value not eq? to #f;
#f is self-evaluating --(eq? #f '#f) is true;
#f is unique;
#f has no special name in the sense that there is no symbol whose value it is (this is probably not the right terminology in Scheme);
there is a canonical true object, #t, although all objects are true other than #f;
there is a unique empty list object, () -- this object is not the same as #f, is not self-evaluating and does not have a name, so (eq? #f '()) is false, but (eq? '() '()) is true, as is (eq? '() (cdr (list 1))), while (if '() 1 2) evaluates to 1 and (eq? () 1) is an error.
Disclaimer: my knowledge of CL is better than my knowledge of Scheme.
In Common Lisp nil/'nil/()/'() represents the same value nil and it is both the empty list and the one false value. In Scheme they are two different values, '() for the empty list and #f as the false value. When translating Common Lisp one needs to determine if the value represents a false value or an empty list. In some cases you will have the empty list being used as a boolean and thus you would need to do (not (null? v)) where CL just does v. The reason for this is that only #f is false in Scheme and thus the empty list is a true value. (if '() #t #f) ; ==> #t
In Common Lisp t can be replaced by #t, but in Scheme there are special symbols in some forms like else in cond that is the idiomatic way to do the alternative term.
I guess you're translating some Common Lisp code to Scheme. In Scheme, the T at the end of a cond expression can be replaced by true, but the idiomatic way is to use an else. And NIL is just the empty list '(), sometimes aliased as null.
Also, be careful with how you define a procedure, you wrote an incorrect opening parenthesis in the first line - the correct way is:
(define listword
(lambda (word)
...))
Or equivalently (and perhaps more idiomatic):
(define (listword word)
...)

Can someone explain equality to me in scheme/racket?

So I stumbled across this today and it has me puzzled.
(define (x) '(1))
(eq? (x) (x)) ;=> #t
(eq? '(1) '(1)) ;=> #f
(define (y) (list 1))
(eq? (y) (y)) ;=> #f
(eq? (list 1) (list 1)) ;=> #f
Can anyone explain what's happening here ?
When compiled this program
(define (x) '(1))
(eq? (x) (x))
(eq? '(1) '(1))
is compiled into (something like):
(define datum1 '(1))
(define datum2 '(1))
(define datum3 '(1))
(define (x) datum1)
(eq? (x) (x))
(eq? datum2 datum3)
Therefore (x) will always return the object stored in datum1.
The expressions (eq? '(1) '(1)) on the other hand will
find out that datum2 and datum3 does not store the same object.
Note: There is a choice for the compiler writer. Many Scheme implementation will compile the above program to:
(define datum1 '(1))
(define (x) datum1)
(eq? (x) (x))
(eq? datum1 datum1)
and then the result will be true in both cases.
Note: The documentation of quote doesn't explicitly state whether multiple occurrences of '(1) in a program will produce the same value or not. Therefore this behavior might change in the future. [Although I believe the current behavior is a deliberate choice]
eq? checks if the objects are the same (think "if the pointer refers to the same address in memory").
In the first case you're working with literals created at compile time. Comparing (and modifying) literals is generally undefined behaviour. Here it looks like procedure x returns the same literal every time, but in the second expression it looks like the 2 literals are not the same. As I said, undefined behaviour.
In the second case you're not working with literals but list creates a new list at execution time. So each call to y or list creates a fresh list.
uselpa's answer is correct.† I wanted to expand on what a quoted datum is, a little further, though.
As you know, all Scheme programs are internally read in as a syntax tree. In Racket, in particular, you use the read-syntax procedure to do it:
> (define stx (with-input-from-string "(foo bar)" read-syntax))
> stx
#<syntax::1 (foo bar)>
You can convert a syntax tree to a datum using syntax->datum:
> (syntax->datum stx)
'(foo bar)
quote is a special form, and what it does is return the quoted portion of the syntax tree as a datum. This is why, for many Scheme implementations, your x procedure returns the same object each time: it's returning the same portion of the syntax tree as a datum. (This is an implementation detail, and Scheme implementations are not required to have this behaviour, but it helps explain why you see what you see.)
And as uselpa's answer says, list creates a fresh list each time, if the list is non-empty. That's why the result of two separate non-empty invocations of list will always be distinct when compared with eq?.
(In Scheme, the empty list is required to be represented as a singleton object. So (eq? '() '()) is guaranteed to be true, as is (eq? (list) '()), (eq? (cdr (list 'foo)) (list)), etc.)
† I would not use the phrasing "undefined behaviour" for comparing literals because that's easily confused with the C and C++ meaning of UB, which is nasal demons, and although the result of comparing literals may not be what you expect, it would not cause your program to crash, etc. Modifying literals is nasal demons, of course.

How do I use and/or instead of if/cond?

I'm new to Scheme programming and I've gotten this task that I just can't find out how to work correctly. I'm supposed to define a procedure with one parameter (a number). If the number is positive I want 1 to be returned, -1 if the number is negative and 0 if it is 0, using only and/or. If and cond is not allowed. I only get #t or #f returned, but you see that's not what I want. Any help or pointers is appreciated
You can solve your problem if you look at the following equivalence, valid when every expj has a value different from #f:
(cond (test1 exp1) (or (and test1 exp1)
(test2 exp2) (and test2 exp2)
... ≡ ...
(testn expn) (and testn expn)
(else expn+1)) expn+1)
Since the function that gets the sign of a number can simply be written in this way:
(define (sign x)
(cond ((> x 0) +1)
((< x 0) -1)
(else 0)))
after applying the above equivalence, since every result is an integer, different from #f, this function becomes equal to the solution proposed also in another answer:
(define (sign x)
(or (and (> x 0) +1)
(and (< x 0) -1)
0))
So, which is the reason of the above equivalence? It depends on the fact that and evaluates its arguments in turn; as soon as one of them is #f, it stops by returning #f, otherwise returns its last argument (and this explains the single branches (and testj expj)); while or evaluates its arguments in turn; as soon as one of them is not #f, it stops by returning it, otherwise returns its last argument (and this explains the chain (or (and ...) (and ...) ... expn+1)).
(define test
(lambda (n)
(or (and (< n 0) -1)
(and (= n 0) 0)
1)))
Part of the trick is understanding that and, if everything evaluates to true, will return the last item it evaluated, while or will return the first thing that successfully evaluates to true. The other part is realizing that everything except for #f is considered "true."
The transformation of and is seen in the report but to not include the actual macros it's basically this:
; only one argument
(and a) ; ===>
a
; one of more
(and a b ...) ; ==>
(if a
(and b ...)
#f)
All arguments must be evaluate to a positive value and the last value is the result, else #f. It short circuits so when something is #f the rest of the expressions are never evaluated.
For or is like this:
(or a) ; ==>
a
(or a b ...) ; ==>
(let ((a-value a))
(if a-value
a-value
(or b ...)))
The first argument that does not evaluate to #f gets returned. If all values are #f the last #f will be the result.
Thus if you want:
(if a b c) ; ==>
(let ((tmpa a))
(or (and atmpa b)
(and (not atmpa) c)) ; not part only important if b can be #f
I use let to prevent evaluating the same expression several times. eg. if you had one that printed something like (begin (display "hello") #f) or it's an expensive calculation then it's necessary or else you can just substitute the variable with the expression. eg. the last would become:
(or (and a b)
(and (not a) c))
That transformed back with no temporary variables become:
(if (if a b #f)
(if a b #f)
(if (not a) c #f))
If b is #f value, then the result is #f because of the last if. Thus everytime a is true b is the result. Everytime it's false, c is the answer. Thus
(if a b c)
So imagine you want to return the first true value in a list.
(define (first-true lst)
(and (not (null? lst))
(car lst)
(first-true (cdr lst))))

Is there anyway to check if a function return nothing in Scheme?

Is there anyway to check if a function return nothing in Scheme?
For example:
(define (f1)
(if #f #f)
)
or
(define (f2) (values) )
or
(define (f3) (define var 10))
How can I check if f return nothing?
Thanks in advance.
Yes. You can wrap the call in something that makes a list of the values. eg.
(define-syntax values->list
(syntax-rules ()
((_ expression)
(call-with-values (lambda () expression)
(lambda g (apply list g))))))
(apply + 5 4 (values->list (values))) ; ==> 9
(null? (values->list (values))) ; ==> #t
Your procedure f2 does return exactly one value and it's undefined in the report (Scheme standard). That means it can change from call to call and the result of (eq? (display "test1") (display "test2")) is unknown.
Implementations usually choose a singleton value to represent the undefined value, but you can not depend on it. Implementations are free to do anything. eg. I know that in at least one Scheme implementations this happens:
(define test 10)
(+ (display 5) (set! test 15))
; ==> 20 (side effects prints 5, and test bound to 15)
It would be crazy to actually use this, but it's probably useful in the REPL.
In GNU Guile the function for checking this is unspecified?:
(unspecified? (if #f #f)); returns #t
(unspecified? '()); returns #f

Getting #<undef> back when calling a scheme function

I have the following code in Scheme:
(define (processExpression lst)
(define operand (car lst))
(define operator1 (cadr lst))
(define operator2 (caddr lst))
(if (list? operand)
(begin
(display "Invalid syntax! Erroring out!")
(quit)
)
)
(if (and (number? operator1) (number? operator2))
;The list was of the form (operand c1 c2)
(simplePrefix lst)
)
(if (and (list? operator1) (number? operator2))
(begin
(list operand operator2 (processExpression operator1))
)
)
)
(define (simplePrefix lst)
(let (
(operand (car lst))
(operator1 (cadr lst))
(operator2 (caddr lst)))
(list operator1 operand operator2)
)
)
(display "Please enter a valid s-expression")
(let ((input (read)))
(display (simplePrefix input))
)
This code takes and s-expression and converts it based on some rules. One rule should be that the expression (+ (+ 1 2) 2) should return (+ 2 (1 + 2)).
Currently when I call this code with that expression I get back the result "#undef>" but I have no idea why. The code should call the simplePrefix function on the (+ 1 2) part of the expression and return (1 + 2) but it does not. Does anyone understand why?
The value of
(if condition
something)
is undefined if condition is false, because there's no else part in the if form. In the R5RS version of Scheme, this is stated (emphasis added):
4.1.5 Conditionals
syntax: (if <test> <consequent> <alternate>)
syntax: (if <test> <consequent>)
Syntax: <Test>, <consequent>, and <alternate> may be arbitrary expressions.
Semantics: An if expression is evaluated as follows: first, <test> is evaluated. If it yields a true value (see section
6.3.1), then <consequent> is evaluated and its value(s) is(are) returned. Otherwise <alternate> is evaluated and its value(s)
is(are) returned. If <test> yields a false value and no
<alternate> is specified, then the result of the expression is
unspecified.
(if (> 3 2) 'yes 'no) ===> yes
(if (> 2 3) 'yes 'no) ===> no
(if (> 3 2)
(- 3 2)
(+ 3 2)) ===> 1
Some Scheme-like languages (e.g., Racket) will actually warn you if you try this:
Welcome to Racket v6.1.
> (if #t
(display "hello"))
stdin::1: if: missing an "else" expression
in: (if #t (display "hello"))
context...:
In Common Lisp, the else part is optional, and defined to be nil if not provided:
This is SBCL 1.2.4.58-96f645d, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
* (if t
(print 'hello))
HELLO
HELLO
* (if nil
(print 'hello))
NIL
The expression
(if condition result)
is not equivalent to
if condition
return result
in other languages.
It doesn't return a value, it has a value.
If the condition is false, that value is undefined.
If it is followed by other expressions in a sequence, the value is ignored and the following expressions are evaluated.
The result of evaluating a function application is the value of the last expression in the function's body
(define (foo)
(if (= 1 1)
"one is one")
"I am still here")
> (foo)
"I am still here"
These two added together lead to the error you're experiencing.

Resources