Common Lisp random dices - random

I´m a beginner of c. Lisp and actually i´ve got some problems with my first code. The topic was a "dicegame" with random numbers. If you get two 1 you win or if you get two 6 you also win.
First i´ve worte this code:
(defun dice ()
(+ (random 6) 1))
(defun dicegame (dice dice)
(and (and (or
(equal (print (dice)) 1)
(equal (print (dice)) 6))
(or
(equal (print (dice)) 1)
(equal (print (dice)) 6)))
(or (equal (print (dice)) (print (dice))))))
(dicegame (dice) (dice))
it isn´t working. I get results with 6 numbers which are nil and i get results with for ex. 3 5 4 5 3 4 which are true. I don´t get that.
Than I wrote a new one which is working:
(defun dicegame-s (dice dice)
(or (and (equalp (print (dice)) 1)
(equalp (print(dice)) 1))
(and (equalp (print(dice)) 6)
(equalp (print(dice)) 6))))
My question is: why is the first one not working and the second one is working.
Thanks!

First of all, dicegame-s isn't really working. There are some problems with your code:
all parameters of both dicegame functions have the exact same name
This should make the parsing of the code fail. You could name them (dice-1 dice-2) instead.
you don't use the arguments you pass to your functions
In your functions, you use (dice), which is a function call. So, instead of using the values given to the functions, you just roll a new dice each time!
So, when you write (dicegame (dice) (dice)), that’s when you are rolling the dice; the function only checks the values, and tells you if you have won.
you print too much
The print function prints a value and returns it; that’s why you sometimes have up to 6 values with dicegame, since each (print (dice)) writes its output. In fact, even in dicegame-s, if both dice are 6, 3 results will be printed.
Instead of calling print every time, you should call it once – at the beginning or the end of the function, or somewhere outside it.
A working example
To correct the previous mistakes, you could do something like that:
(defun dicegame (dice-1 dice-2)
(or (and (equalp dice-1 1)
(equalp dice-2 1))
(and (equalp dice-1 6)
(equalp dice-2 6))))
(dicegame (print (dice)) (print (dice)))

Related

Simplistic way to think of the apply function

In trying to 'reduce' the apply function, is the correct a proper understanding?
For example for (apply func args)
Remove the (apply and matching ).
Inset the func as the first element of the args, moving the outer quote in one level if necessary.
Here would be an application:
; (add-pairs '((1 2)(3 4))) --> (3 7)
(define (add-pairs ps)
(if (null? ps) nil
(cons (+ (car (car ps)) (cadr (car ps))) (add-pairs (cdr ps)))))
(apply add-pairs '(((1 2) (3 4))))
xxxxxxx x
; Remove the "(apply " and matching ")"
add-pairs '(((1 2) (3 4)))
------------^
; Insert the function into the args, moving the quote in one level if required.
(add-pairs '((1 2) (3 4)))
Is the above an accurate way to show how the apply gets added in, or am I missing anything?
The example is unfortunate, as it only leaves one argument after "the opening of the parentheses". But yes, that's how I also think about it. The simpler the better, :) as long as it is correct.
Except that of course the values in the list are first evaluated, so it's not a simply-syntactical process. But as a basic example,
(apply + (list 1 2 3))
==
( + 1 2 3 )
i.e. the parens around the arguments is what goes away.
For a non-trivial example, see
Matrix multiplication in scheme, List of lists
It seems like you know Python. I personally think that apply in Scheme and star operator * in Python are quite similar.
Imagine you want to zip several lists, which were themselves packed inside a list. Trying to call
list_of_lists = [[1, 2],[3, 4]]
zip(list_of_lists)
would not give you [(1, 3), (2, 4)], so you write
zip(*list_of_lists)
# here it's the same as
zip(list_of_lists[0], list_of_lists[1])
using the iterable unpacking operator *. A (pretty full) alternative to this in Racket/Scheme is using an apply function:
(define list-of-lists '((1 2) (3 4)))
(apply zip list-of-lists)
;; here it's the same as
(zip (car list-of-lists) (cadr list-of-lists))
(If, of course, zip in Scheme was defined the same way as in Python, requiring arbitrary number of arguments)
But you can definitely see the difference here, the syntactic one. In Python version of apply we are 'applying' this * to arguments and then pass what was 'returned' to calling function (zip). Scheme acts like a functional language and reverses everything inside out (at least that's how I see it): you're 'applying' apply to a function and its arguments and then it handles everything itself.
The other significant difference is that, of course, apply in Scheme is a normal function, so we can write e.g.
(define (apply-func-to-sum-and-args func args)
(func + args))
(apply-func-to-sum-and-args apply (list 1 2 3))
;; returns 6
Though I believe (correct me if I'm wrong) that this function cannot be written in pure Scheme and it calls some weird C function under the hood.

Why is the empty list produced here in this iteration?

Let's take the following function to get a pair of numbers:
; (range 1 3) --> '(1 2 3)
(define (range a b)
(if (> a b) nil
(cons a (range (+ 1 a) b))))
; generate pair of two numbers with 1 <= i < j <= N
(define (get-pairs n)
(map (lambda (i)
(map (lambda (j) (list i j))
(range 1 (- i 1))))
(range 1 n)))
(get-pairs 2)
; (() ((2 1)))
(get-pairs 3)
(() ((2 1)) ((3 1) (3 2)))
Why does the above produce '() as the first element of the output? Comparing this with python, I would expect it to just give the three pairs, something like:
>>> for i in range(1,3+1): # +1 because the range is n-1 in python
... for j in range(1,i-1+1):
... print (i,j)
...
(2, 1)
(3, 1)
(3, 2)
I suppose maybe it has to do with when i is 1?
(map (lambda (j) (list 1 j)) '())
; ()
Is that just an identity in Scheme that a map with an empty list is always an empty list?
When i is 1, the inner map is over (range 1 0), which is () by your own definition. Since map takes a procedure and a list (or lists) of values, applies the procedure to each value in the list in turn, and returns a list containing the results, mapping any procedure over a list containing no values will return a list containing no values.
It might help to create a simple definition for map to see how this might work. Note that this definition is not fully featured; it only takes a single list argument:
(define (my-map proc xs)
(if (null? xs)
'()
(cons (proc (car xs))
(my-map proc (cdr xs)))))
Here, when the input list is empty, there are no values to map over, so an empty list is returned. Otherwise the procedure proc is applied to the first value in the input list, and the result is consed onto the result of mapping over the rest of the list.
A couple of observations:
First, the empty list is not represented by nil in either standard Scheme or vanilla Racket, and you should not be using it. In the early days of Scheme nil was allowed as a crutch for programmers coming from other lisps, but this has not been the case for a long time. I don't think that it was ever in any of the RnRS standards, but nil may have survived in some specific implementations until maybe R4RS (1991). SICP was from that era. Today you should use '() to represent empty list literals in Scheme so that your code can run on any Scheme implementation. Racket's #lang sicp allows code directly from the book to be run, but that should not keep you from using the common notation. Note that Common Lisp does use nil as a self-evaluating symbol to represent both the empty list, and boolean false. Seeing this in Scheme just doesn't look right today.
Second, you will probably be led astray more often than to wisdom by thinking in terms of Python when trying to understand Scheme code. In this particular case, map is an iteration construct, but it is not the same thing as a for loop. A for loop is usually used for side-effects, but map is used to transform a list. Scheme has a for-each form which is meant to be used for its side-effects, and in that sense is more like a for loop. The Python version that is posted above is not at all like the Scheme version, though. Instead of returning the results in a list, the results are printed. In the Scheme code, when i is 1, the inner mapping is over (range 1 0) --> (). But, in the Python code, when i is 1, the inner loop is over range(1, 1), so the body of this for loop is not executed and nothing is printed.
Better to think carefully about the Scheme code you want to understand, falling back on basic definitions, than to cobble together a model based on Python that has possibly unconsidered corner cases.

Procedure printf in Scheme

For example, when I use the procedure printf on the list '((2 t r d)), the last line in my output is
'(#<void>)
and the number of times '(#<void>) appears depend on the number of list nested. Can you please explain this for me???
This is my printf function
(define counting
(lambda (lst)
(if (null? lst)
'()
(printf "~a, ~s\n" (car lst) (length (cdr lst))))))
I have try to other procedure like fprintf and using this form
(fprintf (current-output-port) "~a, ~s\n" (car lst) (length (cdr lst)))
Same thing happens!
AFAIK there is no such procedure in the Scheme standard so you might need to add a tag for a implementation that has it. I know racket has printf.
A (display x) (and (printf x) in racket) alone usually don't display so what produced (#<void>) is not in the question. In Scheme every procedure evaluates to a value. To illustrate this try doing:
(map display '(1 2 3 4))
Which will return a list with 4 unspecified values since map makes a list of the results. display (and printf in racket) prints the result of the evaluation of the argument but doesn't need to return anything since the standard doesn't say that is should. Most implementations do this by returning an undefined object, but some actually return the argument too. The main function of them is to do side effect of displaying something on screen and that it has done. for ignoring return values you can use for-each which is map just for side effects.
(for-each display '(1 2 3 4))
When that said in Scheme it's normal that every procedure return something and you misread output with the REPLs printing of the returned values.
You said that 'the last line of your output is '(#<void>) - this is occurring because your Scheme environment is displaying 1) what you want to be printed and 2) the returned value of the evaluated expression. For example
> (list (display 1))
1(#<void>)
The '1' is printed and then the list result is printed. Since you are typing in an interactive session you will always get the returned value displayed. You can't really hide the returned value however most Schemes will recognize a 'undefined' return value and not print it.
> (display 1)
1
In the above, even though display returns #<void> the interpreter knows not to show it.

Map, Filter, Foldr in DrRacket/Scheme

Programming language: Scheme/DrRacket
We're currently going over map, filter, and foldr in my comp sci class. I understand that all three can be used to create abstract functions, but I am honestly a little confused about the difference between the three and when I'd use each one.
Anyone care to explain what each is used for and how they are different? Unfortunately my book is not very clear.
The basic idea is that all three are ways of applying some function to all the elements of a list.
Map is perhaps the simplest--you just apply the function to each element of the list. This is basically the same as a for-each loop in other languages:
(map (lambda (x) (+ x 1)) '(1 2 3))
=> (2 3 4)
Basically, map is like this: (map f '(1 2 3)) is the same as (list (f 1) (f 2) (f 3)).
Filter is also simple: the function acts like an arbiter, deciding whether to keep each number. Imagine a really picky eater going through a menu and whining about the things he won't eat ;)
(filter (lambda (x) (equal? x 1)) '(1 2 3))
=> (1)
Fold is the hardest to understand, I think. A more intuitive name would be "accumulate". The idea is that you're "combining" the list as you go along. There are some functions in ever day use that are actually folds--sum is a perfect example.
(foldr + 0 '(1 2 3))
=> 6
You can think of the fold as taking the function and putting it between each element in the list: (foldr + 0 '(1 2 3)) is the same as 1 + 2 + 3 + 0.
Fold is special because, unlike the other two, it usually returns a scalar value--something that was the element of the list rather than the list itself. (This isn't always true, but think of it this way for now anyway.)
Note that I may not have gotten every detail of the code perfect--I've only ever used a different, older implementation of Scheme so I might have missed some Racket details.
I can recommend these finger exercises (and the text that comes before):
http://htdp.org/2003-09-26/Book/curriculum-Z-H-27.html#node_idx_1464

Function in Scheme that checks whether the length of a list is even

Hi I have edited the code for function in scheme that checks whether the length of a list is even.
(define even-length?
(lambda (l)
(cond
((null? l)#f)
((equal? (remainder (length(l)) 2) 0) #t)
(else #f))))
Is it corrrect?
You seem to have the syntax for if and cond all mixed up. I suggest referring to the language reference. if only has two clauses, and you don't write else for the else clause. (Hint: You shouldn't need an if for this function at all.)
Also, consider whether it makes sense to return null if the list is null; probably you want to return #t or #f instead.
Oh yeah, and rewrite your call of length to be a proper prefix-style Scheme function call.
The code is clearly wrong -- your %2 assuming infix notation, where Scheme uses prefix notation. The syntax of your if is wrong as well -- for an if, the else is implicit (i.e. you have if condition true-expression false-expression. In this case, you're trying to return #t from one leg and #f from another leg -- that's quite unnecessary. You can just return the expression that you tested in the if.
Edit: one other detail -- you should really rename this to something like even-length?. Even if I assume that it's a predicate, a name like even would imply to me that (even 3) should return #f, and (even 4) should return #t -- but in this case, neither works at all.
Edit2: Since mquander already gave you one version of the code, I guess one more won't hurt. I'd write it like:
(define (even-length? L) (even? (length L)))
I don't like using lower-case 'l' (but itself) much, so I've capitalized it. Since even? is built in, I've used that instead of finding the remainder.
Running this produces:
> (even-length? `(1 2 3))
#f
> (even-length? `(1 2 3 4))
#t
>
This is different from what you had in one respect: the length of an empty list is 0, which is considered an even number, so:
(even-length? `())
gives #t.
(define even-length? (lambda (l)
(even? (length l))))
Usage:
(even-length? '(1 2 3 4))
#t
(even-length? '(1 2 3 ))
#f
As others pointed out, there is indeed a predicate to check evenness of a number, so why not using it?
EDIT: I just saw Jerry Coffin wrote the same function witht the same example... Sorry for repeating :-)

Resources