Racket has only foldl and foldr, which require initial value. Haskell in addition has foldl1 and foldr1, which instead of applying a function on the initial value and the first element, applies to first and second element. Currently i implemented them as:
(define (foldl1 f xs)
(foldl f (first xs) (rest xs)))
Is there a better way?
There is a better way, just (require srfi/1) and use reduce and reduce-right. :-D
What you are describing looks like reduce in CL. Your procedure looks ok except it would fail if the list is empty.
Be aware that first and rest are not the same as car and cdr since they only work on proper lists. eg.
(first '(a b c d e . f))
;;==>
;;first: contract violation
;; expected: (and/c list? (not/c empty?))
;; given: '(a b c d e . f)
Now. For racket to signal here it must have traversed the whole list to make sure it ends with null and since it didn't it signaled an error. I did a small test and found out that sorting a 2 million list used 32% more time with first/rest.
Related
I am learning about racket/scheme and came across an online resource that said, if a function written using a cond gives true or false, it can be rewritten using only not, and, and or. I have worked out some simple examples where I was able to to convert cond statements into a statement only involving not and and or. My question is if there is a way that the logic can be "seen" right away when converting between these two types of statements. I understand that it is not always practical to convert every cond statement into a combination of not's and's and or's but I am interested in learning about the logic behind the process of converting.
Thanks in advance.
(If something about the question does not make sense, leave a comment and I will try clarifying what I want to understand)
All conditional expressions (and not only those evaluating to true/false) can be rewritten using only boolean combinators. This is because of how logical operators are evaluated in Scheme/Racket. For instance, logically (and a b) would be true if both a and b are true, and otherwise false. But in Racket, the result of (and a b) is b if both a and b are truthy, and otherwise false. That is, evaluation proceeds to the right until either the last argument or a falsy value is encountered. At that point, evaluation stops and that value (which could be a boolean but needn't be) is returned. It's because and and or don't simply produce boolean output that they can be used to stand in for conditional expressions.
E.g.
(if #t 'hello 'bye) ;=> hello
(or (and #t 'hello) 'bye) ;=> hello
(if #f 'hello 'bye) ;=> bye
(or (and #f 'hello) 'bye) ;=> bye
(cond [#f 'hello]
[#f 'bye]
[#t 'aloha]) ;=> aloha
(or (and #f 'hello)
(and #f 'bye)
(and #t 'aloha)) ;=> aloha
But you wouldn't usually want to use them that way since they're hard to read. As a general guideline, use if and cond in most cases, rather than elementary boolean operators. If you only care about taking action on a positive or negative result of the conditional, then you could use when or unless. If you do care about handling both positive and negative results, but one of them is a boolean result such as this example:
(if (positive? n)
#t
(even? n))
... then this would be a case where a boolean operator would be preferable, like so:
(or (positive? n) (even? n))
If both arms of the if conditional are boolean values, like this:
(if (> n 3)
#t
#f)
... then just replace the entire conditional expression with the condition itself:
(> n 3)
Otherwise, stick to if and cond.
Once you convert a cond to nested ifs, you can always turn it into and or and not like this:
(if A B C) --> (or (and A B) (and (not A) C))
However, if you do this blindly, you will get a much more complicated expression than what you could get, so I would add a couple more transformations you can use:
(if A B #f) --> (and A B)
(if A B #t) --> (or (not A) B)
(if A #f C) --> (and (not A) C)
(if A #t C) --> (or A C)
(note: that or above might return a different truthy-value other than #t, making it technically different but equivalent-when-used-as-a-boolean)
Another thing I should note is that sometimes you can transform a multi-branch cond into and or not without transforming into ifs first. For example a 3-branch cond:
(cond [A B]
[C D]
[else E])
-->
(or (and A B)
(and (not A) C D)
(and (not A) (not C) E))
Or a 4-branch cond:
(cond [A B]
[C D]
[E F]
[else G])
-->
(or (and A B)
(and (not A) C D)
(and (not A) (not C) E F)
(and (not A) (not C) (not E) G))
Each and corresponds to a cond-branch, and each cond-branch's and has nots in it for every previous condition, in addition to its own condition.
A more generic rule you can apply:
for i from 1 through n,
(cond [Q_i A_i]
...
[else E])
-->
on each i, for j from 1 through i-1,
(or (and (not Q_j) ... Q_i A_i)
...
(and (not Q_i) ... E)
First of all, you need to desugar cond language into a sequence of if-then-else sequences, which is trivial.
After that, you can rewrite if conditionals into boolean operators. You can look into a manual of propositional logic to learn this. Or look here.
Btw. It is forbidden to paste your homework on stack overflow.
I am currently studying about Lisp but I still don't get quote.
Why use quote in Lisp?
And I got a problem here which is hard to understand to me.
(car (car '((a b) c d)))
The above gives A.
But I don't know why the result is A because there is no quote first car after.
quote is an operator; its meaning only kicks in when it is the head of a Lisp expression which is evaluated. The syntax 'X stands for (quote X): the Lisp reader translates a prefix apostrophe, followed by any syntactic unit X denoting one object, into the syntax (quote X). The quote expression, when evaluated, returns the syntax X itself as the value, rather than the value of the syntax. For instance (quote (+ 1 2)) returns the three element list (+ 1 2), rather than the value of the expression (+ 1 2) which is 3. quote effectively reflects a piece of the program's list-based syntax back into the running program as a value.
In the expression:
(car (car '((a b) c d)))
we simply have a nested function application to a value:
(car (car value))
This value is the result of a quote expression, and so the value is the object ((a b) c d). This object started out as a piece of syntax wrapped inside quote, but is now a run-time value being passed to the car function. The inner car produces the first element of the list, returning (a b). This (a b) value is passed to the outer car, which retrieves the a.
Lisp provides quote because it is a homoiconic language. The principal data structures manipulated in that language have a printed notation, and that printed notation is used to write programs also. Thus programs are understood to be made out of a data structure. In this kind of language, suppose you want to be able to use any data structure as a literal. Of course, that creates confusion because the data uses the same notation as the code, and some data structures look like valid syntax. You need an operator which you can wrap around a piece of syntax to say, "this is literal data; do not evaluate this as an expression, but just the data that it looks like".
This is exactly the same like when we use English to talk about English. We have to use quotes—at least when we write this talk down. A sentence like:
A penny saved is a penny earned is a good old proverb.
is badly written. Of course we understand what it means because our brains are good at dealing with ambiguity and mistakes, but it appears to be saying that a penny is a proverb. We need quotes:
"A penny saved is a penny earned" is a good old proverb.
See? The quote says that this sentence is not a relative clause of my sentence; it's text that my sentence is talking about (which happens to be in the same language that I'm using to talk about it). This is why the Lisp operator is called quote: it's related to this type of quoting.
Why use quote
Think of the quote as an indication that it's data and not to be thought of as code:
(cons 1 2) ; ==> (1 . 2) (a cons with car as 1 and cdr as 2)
'(cons 1 2) ; ==> (cons 1 2) (a list with the symbol cons and the numbers 1 and 2)
You see in the first that is not quoted it's executed and the result is the result of the cons function. In the second you could say quote is executed and it evaluates soley to it's argument. Note that 'x is just an abbrevation for (quote x) and both thus evaluate to x while without quote it would evaluate to the value bound to the variable x.
Nested functions
When you nest functions like (car (car '((a b) c d)))) you'll se why you need to quote since all arguments in functions are evaluated. Thus before the outer car can be applied it needs to evaluate it's argument (car '((a b) c d))) and before the inner car can do it's job it needs to evaluate it's argument '((a b) c d)). We know that '((a b) c d)) becomes ((a b) c d)) and car of this is (a b). The outer car then works on (a b) and thus a is the result. If you would have put the quote like this (car '(car ((a b) c d)))) then the innser car is just a symbol in the data structure and not a function. car evaluates its argument to be (car ((a b) c d))) and car of that is the symbol car.
'((a b) c d)) ; ==> ((a b) c d))
(car '((a b) c d)) ; ==> (a b)
(car (car '((a b) c d))) ; ==> a
'(car ((a b) c d)) ; ==> (car ((a b) c d))
(car '(car ((a b) c d))) ; ==> car
Also know that if you put quotes inside quoted data, like ''x only the outer quote is taken off and the rest is data. The result is (quote x) or 'x depending on the display settings but since it's already data quote here is just a symbol. (car ''x) ; ==> quote (symbol)
It seems like in order to use multiple return values in Racket, I have to either use define-values or collect them into a list with (call-with-values (thunk (values-expr)) list). In the latter case, why would someone to choose to return multiple values instead of a list, if just have to collect them into a list anyway? Additionally, both of these are very wordy and awkward to work into most code. I feel like I must be misunderstanding something very basic about multiple-return-values. For that matter, how do I write a procedure accepting multiple return values?
Although I may be missing some of the Scheme history and other nuances, I'll give you my practical answer.
First, one rule of thumb is if you need to return more than 2 or 3 values, don't use multiple values and don't use a list. Use a struct. That will usually be easier to read and maintain.
Racket's match forms make it much easier to destructure a list return value -- as easy as define-values:
(define (f)
(list 1 2))
(match-define (list a b) (f))
(do-something-with a b)
;; or
(match (f)
[(list a b) (do-something-with a b)])
If you have some other function, g, that takes a (list/c a b), and you want to compose it with f, it's simpler if f returns a list. It's also simpler if both use a two-element struct. Whereas call-with-values is kind of an awkward hot mess, I think.
Allowing multiple return value is an elegant idea, because it makes return values symmetric with arguments. Using multiple values is also faster than lists or structs (in the current implementation of Racket, although it could work otherwise).
However when readability is a higher priority than performance, then in modern Racket it can be more practical to use a list or a struct, IMHO. Having said that I do use multiple values for one-off private helper functions.
Finally, there's a long, interesting discussion on the Racket mailing list.
Racket doc gives us the quintessential example why, in disguise:
> (let-values ([(q r) (quotient/remainder 10 3)])
(if (zero? r)
q
"3 does *not* divide 10 evenly"))
"3 does *not* divide 10 evenly"
We get two values directly, and use them separately in a computation that follows.
update: In Common Lisp, with its decidedly practical, down-to-the-metal, non-functional approach (where they concern themselves with each extra cons cell allocation), it makes much more sense, especially as it allows one to call such procedures in a "normal" way as well, automatically ignoring the "extra" results, kind of like
(let ([q (quotient/remainder 10 3)])
(list q))
But in Racket this is invalid code. So yeah, it looks like an extraneous feature, better to be avoided altogether.
Using list as the consumer defeats the purpose of multiple values so in that case you could just have used lists to begin with. Multiple values is actually a way of optimization.
Semanticly returning a list and several values are similar, but where you return many values in a list effort goes into creation of cons cells to make the list and destructuring accessors to get the values at the other end. In many cases however, you wouldn't notice the difference in performance.
With multiple values the values are on the stack and (call-with-values (lambda () ... (values x y z)) (lambda (x y z) ...) only checks the number to see if it's correct.. If it's ok you just apply the next procedure since the stack has it's arguments all set from the previous call.
You can make syntactic sugar around this and some popular ones are let-values and SRFI-8 receive is a slightly simpler one. Both uses call-with-values as primitive.
values is handy because it
checks that the number of elements returned is correct
destructures
For example, using
(define (out a b) (printf "a=~a b=~a\n" a b))
then
(let ((lst (list 1 2 3)))
(let ((a (first lst)) (b (second lst))) ; destructure
(out a b)))
will work even though lst has 3 elements, but
(let-values (((a b) (values 1 2 3)))
(out a b))
will not.
If you want the same control and destructuring with a list, you can however use match:
(let ((lst (list 1 2)))
(match lst ((list a b) (out a b))))
Note that he creation of the structure, e.g. (list 1 2) vs (values 1 2) is equivalent.
is there a function like find in lisp that returns true instead of the element we're trying to find?
example:
I want it to do
(find 'x '(a c x)) = t
not
(find 'x '(a c x)) = x
Also, the reason I am asking is because I am trying to reach the deepest element in a list. My plan was to flatten the list every time i recursively called it.
I would then stop the recursive call when
(mapcar 'atom list)
would tell me every atom in there is true.
Do you believe this is a good approach to this problem?
There's no such function, but it can't be easier to write one:
(defun find-t (&rest args)
(when (apply #'find args)
t))
Also instead of (mapcar 'atom list) you can use (every #`(eql t %) list), i.e. check that every item in list is exactly t. (Here #`() is syntactic sugar for one-argument lambdas, that I use.)
But overall it's unclear, what you're trying to achieve with all this. Can you elaborate on what you're trying to do?
Working with DrScheme (language-- Pretty Big). Trying to pass the result of an expression to a variable that can later be used in another expression. Here is a simplified version of the problem:
Definitions window:
(define (tot a b c) (+ a b c))
(define (tot2) (+ (tot a b c) 1))
Interpreter window
> (tot 5 6 7)
18
> (tot2)
. . reference to undefined identifier: a
The result I want, of course, is 19. It would be easy to have DrScheme do all the algebra at once, but I need to have it solve the first expression, then solve the second expression based on the result of the first.
Is this what you are looking for?
(define (tot a b c) (+ a b c))
(define (tot2 a b c) (+ (tot a b c) 1))
Then
(tot2 5 6 7)
should result in 19.
If you want tot2 assigned to the integer value rather than to a function,
(define (tot a b c) (+ a b c))
(define tot2 (+ (tot 5 6 7) 1))
assigns the result of the expression (+ (tot 5 6 7) 1) to the name tot2
Scheme is lexically scoped: so a, b, and c will only exist for the dynamic extent of tot.
The dynamic extent of a procedure call is the period between when the call is initiated and when it returns (via gnu).
You're imagining a "persistence" that isn't there, though it's probably plausible, given prior experience with math.
That is: if I'm solving a math problem, and I say that x equals 5, well then x should stay equal to five for the remainder of the problem; until I erase the board, for instance.
So, can you write a programming language like this? Yes! In fact, I could write a small macro in DrScheme for you that produced exactly the behavior you appear to be looking for: it would set up a global table of variables so that every variable binding caused an update to this single table of variables.
BUT! All of the programmers I surveyed (one) (okay, it was me) agreed that this would be a very bad idea.
To see why, imagine that I have a large program that contains several variables called 'a'. Then, any time someone in part A of the program calls a function with a variable named 'a', then part B of the program will suddenly change its behavior. This will make it nearly impossible to reason about the behavior of larger programs.
More generally, this is the problem with "state" and "mutation".
For this reason, you cannot refer to variables other than the ones that are "in scope". That is, those variables whose binding form (in this case a 'define') encloses the reference.
Based on your comments on John's answer, I think what you want is just to assign the result of each function call to a variable (either one variable for each or stick them all in a list) and then add those results together.
After reading through everyone's comments, I realized that I was confusing two issues: having the interpreter evaluate an expression with variables, and actually supplying values for those variables. Because of this confusion, the questions I asked did not make sense. Here's a simplified version of the solution. As you can see, it is embarrassingly simple-- I just used "read" to have the user enter the values.
(define a (read))
(define b (read))
(define c (read))
(define d (read))
(define ee (read))
(define f (read))
(define tot (+ a b c))
(define tot2 (+ d ee f))
(define grandtotal (+ tot tot2))
(display grandtotal)
I used this approach with the actual program and now have a nice little application that totals my hours worked for the week. Thanks everyone for your patient assistance.