Map-filter CPS version in Scheme - filter

I'm wondering, is there any implementation of map-filter in CPS version in Scheme?
example:
(map-filter square even? '(1 2 3 4)) -> '(4 16)

You can define map-filter& using filter& and map&:
(define (map-filter& proc& pred?& lst k)
(filter& pred?&
lst
(lambda (new-lst)
(map& proc& new-lst k))))

[This answer give two versions of the function the person described: not CPS versions of it. I think the question is ambiguous but this is probably not the right answer: Sylwester's is.]
If what you want is what you've described (which I'm fairly sure is not CPS), then something like this works:
(define (map-filter mapper filterer lst)
(map mapper (filter filterer lst)))
In Racket then this might be better as this:
(define (map-filter mapper filterer lst)
(for/list ([e (in-list lst)]
#:when (filterer e))
(mapper e)))
which perhaps has a better chance of avoiding consing an intermediate list but smells nastier to me.

Related

Adjacent difference in Racket

C++ has a handy algorithm std::adjacent_difference which computes the differences between the next/previous of elements of the range.
The Racket implementation is straightforward:
(define (adjacent-difference f lst)
(if(null? (cdr lst))
'()
(cons (f (cadr lst)(car lst))
(adjacent-difference f (cdr lst)))))
however we have a lot of handy built-in algorithms inside the Racket so I wanted to reuse them.
The first idea was:
(map f (cdr lst) lst)
Oops, the sizes of the lists are different, we cannot use map in this way.
I can cheat like this:
(map f (append (cdr lst) '(0)) lst) ; do not use the last element
but it is a dirty solution.
Any ideas how to do it without writing a new function?
Here is a short version:
(define (adjacent-difference f xs)
(for/list ([x xs] [y (cdr xs)])
(f y x)))
Here x and y runs though the elements of xs and (cdr xs)
in parallel. Since (cdr xs) is the shorter than xs the loop
ends when there is no more elements in (cdr xs).
In the map defined in SRFI-1 List library different sized lists are allowed with the requirement that at least one is finite. It will only step as many times as the shortest list.
#lang racket
;; import map from srfi-1. This shadows the one from racket/base
(require (only-in srfi/1 map))
(define (adjacent-difference f lst)
(map f (cdr lst) lst))
For completeness I'll include the imports needed for the same code to work in Scheme:
#!r6rs
(import (except (rnrs) map)
(only (srfi :1) map))
In the next version of Scheme, R7RS, SRFI-1 is the standard list library. Thus this should work in the R7RS "red edition":
#!r7rs
(import (scheme)
(scheme list))
If I understand what you want, it isn't only "dirty" but it isn't a solution, since appending the zero at the end means you have more elements than you should. For a three-item list you should only have two differences, right? Or do you always want to pull in default elements?
How about making your own map?
(define (stalling-map proc . args)
(if (ormap null? args)
'()
(cons (apply proc (map car args))
(apply stalling-map proc (map cdr args)))))
;;;;
Welcome to DrRacket, version 6.12 [3m].
> (let ((lst '(1 3 7 10 11)))
(stalling-map - (cdr lst) lst))
'(2 4 3 1)
>

How to implement call-with-values to match the values example in R5RS

R5RS says...
Values might be defined as follows:
(define (values . things)
(call-with-current-continuation
(lambda (cont) (apply cont things))))
It doesn’t, however, say how call-with-values might be implemented if values were implemented this way. So, if values is implemented this way, how would call-with-values be implemented?
(This came up because I was trying to get some code that used call-with-values to work with TinyScheme, which doesn’t support it. I managed by faking values and call-with-values with lists, but—when I saw this in R5RS—I wanted to know if this might be a better workaround.)
Kent Dybvig defines call/cc, values and call-with-values thusly:
(define call/cc call/cc)
(define values #f)
(define call-with-values #f)
(let ((magic (cons 'multiple 'values)))
(define magic?
(lambda (x)
(and (pair? x) (eq? (car x) magic))))
(set! call/cc
(let ((primitive-call/cc call/cc))
(lambda (p)
(primitive-call/cc
(lambda (k)
(p (lambda args
(k (apply values args)))))))))
(set! values
(lambda args
(if (and (not (null? args)) (null? (cdr args)))
(car args)
(cons magic args))))
(set! call-with-values
(lambda (producer consumer)
(let ((x (producer)))
(if (magic? x)
(apply consumer (cdr x))
(consumer x))))))
The short answer is: You can't
The nifty implementation of values does not change the fact that there is no way to implement the other procedures if you don't have any of them to poke at the values. If you had one way to peek then you could implement the others with that.
(+ (values 4 5))
(apply + (values 4 5))
Doesn't work and that's why you need those other primitives.
When that said. There is no difference between returning more values and returning lists with values since the difference is optimization. You could make a macro that treats both of them as a binding and then the way you use them would be the same. The difference in performance is some pointer jumping and some consing which is reasonable fast for any lisp implementation. Heres a minimalistic implementation that will work given your code is correct:
(define values list)
(define (call-with-values producer consumer)
(apply consumer (producer)))

Sorting algorithm lisp-scheme

I have decided to learn some functional language and I hooked up with the lisp-scheme after all.
I am trying to make a function which checks if a list is sorted, either with lowest first getting higher or vice versa, and if it can be sorted it should return true else false.
This is my first code, working only if the list is increasing (or equal).
(define sorted?
(lambda (lst)
(cond ((empty? lst) #t)
(else (and (<= (car lst) (cadr lst))
(sorted? (cdr lst)))))))
clarification: something like (sorted? '(1 2 3 4 5)) and (sorted? '(5 4 3 2 1)) should return true, else if not sorted false of course.
How am I supposed to think when programming in a functional style? The syntax seems straight-forward but I'm not used to the logic.
Specific implementation
I'd take Óscar López's answer and go one step further:
(define sorted? (lambda (lst)
(letrec ((sorted-cmp
(lambda (lst cmp)
(cond ((or (empty? lst) (empty? (cdr lst)))
#t)
(else (and (cmp (car lst) (cadr lst))
(sorted-cmp (cdr lst) cmp)))))))
(or (sorted-cmp lst <=) (sorted-cmp lst >=)))))
The biggest difference between this version and his is that sorted? now defines Óscar's version as an internal helper function using letrec and calls it both ways.
Functional Thinking
You actually chose a good example for illustrating some aspects of how Scheme views the world, and your implementation was off to a very good start.
One important functional principle involved in the solution to this problem is that anything you could put (**here** more stuff '(1 2 3 4)), you can pass around as an argument to another function. That is, functions are first class in a functional programming language. So the fact that you were using <= in your comparison means that you can pass <= as a parameter to another function that makes a comparison accordingly. Óscar's answer is a great illustration of that point.
Another aspect of this problem that embodies another common functional pattern is a function that consists primarily of a (cond) block. In many functional programming languages (Haskell, ML, OCaml, F#, Mathematica), you get stronger pattern matching abilities than you get, by default in Scheme. So with (cond) in Scheme, you have to describe how to test for the pattern that you seek, but that's usually fairly straightforward (for example the (or (empty? lst) (empty? (cdr lst))) in this implementation.
One final functional programming pattern that I see as well-embodied in this problem is that many functional programming solutions are recursive. Recursion is why I had to use letrec instead of plain ol' let.
Almost anything you can do by operating on the first element (or 2 elements as in this case) and then repeating the operation on the tail (cdr) of the list you do that way. Imperative for- or while-style loops aren't impossible in Scheme (although they are pretty much impossible in pure functional languages such as Haskell), they're slightly out of place in Scheme under many circumstances. But Scheme's flexibility that allows you, as the developer, to make that decision enables important performance or maintainability optimizations in certain circumstances.
Continuing exploration
My first implementation of sorted? for my answer here was going to decide which comparison operator to pass to sorted-cmp based on what it saw in the list. I backed off on that when I spotted that a list could start with two equal numbers '(1 1 2 3 4 5). But as I think more about it, there's definitely a way to track whether you've decided a direction yet and, thus, only have one call required to sorted-cmp. You might consider exploring that next.
You almost got it right, look:
(define sorted?
(lambda (lst)
(cond ((or (empty? lst) (empty? (cdr lst)))
#t)
(else (and (<= (car lst) (cadr lst))
(sorted? (cdr lst)))))))
A little modification in the base case, and you're all set. It's necessary to stop when there's only one element left in the list, otherwise the cadr expression will throw an error.
For the second part of your question: If you want to check if it's sorted using a different criterion, simply pass the comparison function as an argument, like this:
(define sorted?
(lambda (lst cmp)
(cond ((or (empty? lst) (empty? (cdr lst)))
#t)
(else (and (cmp (car lst) (cadr lst))
(sorted? (cdr lst) cmp))))))
(sorted? '(1 2 3 4 5) <=)
> #t
(sorted? '(5 4 3 2 1) >=)
> #t
Now if you want to know if a list is sorted in either ascending order or in descending order:
(define lst '(1 2 3 4 5))
(or (sorted? lst >=) (sorted? lst <=))
> #t
As you can see, functional programming is about defining procedures as generic as possible and combining them to solve problems. The fact that you can pass functions around as parameters helps a great deal for implementing generic functions.
I'm going to take your question to mean, more specifically, "if I already program in an imperative language like C or Java, how do I adjust my thinking for functional programming?" Using your problem as an example, I'm going to spend my Saturday morning answering this question in long form. I'll trace the evolution of a functional programmer through three stages, each a successively higher plane of zen - 1) thinking iteratively; 2) thinking recursively; and 3) thinking lazily.
Part I - Thinking Iteratively
Let's say I'm programming in C and I can't or won't use recursion - perhaps the compiler does not optimize tail recursion, and a recursive solution would overflow the stack. So I start thinking about what state I need to maintain. I imagine a little machine crawling over the input. It remembers if it is searching for an increasing or a decreasing sequence. If it hasn't decided yet, it does so based on the current input, if it can. If it finds input headed in the wrong direction, it terminates with zigzag=true. If it reaches the end of the input, it terminates with zigzag=false.
int
zigzag(int *data, int n)
{
enum {unknown, increasing, decreasing} direction = unknown;
int i;
for (i = 1; i < n; ++i)
{
if (data[i] > data[i - 1]) {
if (direction == decreasing) return 1;
direction = increasing;
}
if (data[i] < data[i - 1]) {
if (direction == increasing) return 1;
direction = decreasing;
}
}
/* We've made it through the gauntlet, no zigzagging */
return 0;
}
This program is typical of C programs: it is efficient but it is difficult to prove that it will do the right thing. Even for this simple example, it's not immediately obvious that this can't get stuck in an infinite loop, or take a wrong turn in its logic somewhere. Of course, it gets worse for more complicated programs.
Part II - Thinking Recursively
I find that the key to writing readable programs in the spirit of functional languages (as opposed to just trying to morph an imperative solution into that language) is to focus on what the program should calculate rather than on how it should do it. If you can do that with enough precision - if you can write the problem out clearly - then most of the time in functional programming, you're almost at the solution!
So let's start by writing out the thing to be calculated in more detail. We want to know if a list zigzags (i.e. decreases at some point, and increases at another). Which lists meet this criterion? Well, a list zigzags if:
it is more than two elements long AND
it initially increases, but then decreases at some point OR
it initially decreases, but then increases at some point OR
its tail zigzags.
It's possible to translate the above statements, more or less directly, into a Scheme function:
(define (zigzag xs)
(and (> (length xs) 2)
(or (and (initially-increasing xs) (decreases xs))
(and (initially-decreasing xs) (increases xs))
(zigzag (cdr xs)))))
Now we need definitions of initially-increasing, initially-decreasing, decreases, and increases. The initially- functions are straightforward enough:
(define (initially-increasing xs)
(> (cadr xs) (car xs)))
(define (initially-decreasing xs)
(< (cadr xs) (car xs)))
What about decreases and increases? Well, a sequence decreases if it is of length greater than one, and the first element is greater than the second, or its tail decreases:
(define (decreases xs)
(letrec ((passes
(lambda (prev rest)
(cond ((null? rest) #f)
((< (car rest) prev)
#t)
(else (passes (car rest) (cdr rest)))))))
(passes (car xs) (cdr xs))))
We could write a similar increases function, but it's clear that only one change is needed: < must become >. Duplicating so much code should make you uneasy. Couldn't I ask the language to make me a function like decreases, but using > in that place instead? In functional languages, you can do exactly that, because functions can return other functions! So we can write a function that implements: "given a comparison operator, return a function that returns true if that comparison is true for any two successive elements of its argument."
(define (ever op)
(lambda (xs)
(letrec ((passes
(lambda (prev rest)
(cond ((null? rest) #f)
((op (car rest) prev)
#t)
(else (passes (car rest) (cdr rest)))))))
(passes (car xs) (cdr xs)))))
increases and decreases can now both be defined very simply:
(define decreases (ever <))
(define increases (ever >))
No more functions to implement - we're done. The advantage of this version over the C version is clear - it's much easier to reason that this program will do the right thing. Most of this program is quite trivial with all the complexity being pushed into the ever function, which is a quite general operation that would be useful in plenty of other contexts. I am sure by searching one could find a standard (and thus more trustworthy) implementation rather than this custom one.
Though an improvement, this program still isn't perfect. There's lots of custom recursion and it's not obvious at first that all of it is tail recursive (though it is). Also, the program retains faint echos of C in the form of multiple conditional branches and exit points. We can get an even clearer implementation with the help of lazy evaluation, and for that we're going to switch languages.
Part III - Thinking Lazily
Let's go back to the problem definition. It can actually be stated much more simply than it was in part II - "A sequence zigzags (i.e. is non-sorted) if it contains comparisons between adjacent elements that go in both directions". I can translate that sentence, more or less directly, into a line of Haskell:
zigzag xs = LT `elem` comparisons && GT `elem` comparisons
Now I need a way to derive comparisons, the list of comparisons of every member of xs with its successor. This is not hard to do and is perhaps best explained by example.
> xs
[1,1,1,2,3,4,5,3,9,9]
> zip xs (tail xs)
[(1,1),(1,1),(1,2),(2,3),(3,4),(4,5),(5,3),(3,9),(9,9)]
> map (\(x,y) -> compare x y) $ zip xs (tail xs)
[EQ,EQ,LT,LT,LT,LT,GT,LT,EQ]
That's all we need; these two lines are the complete implementation -
zigzag xs = LT `elem` comparisons && GT `elem` comparisons
where comparisons = map (\(x,y) -> compare x y) $ zip xs (tail xs)
and I'll note that this program makes just one pass through the list to test for both the increasing and decreasing cases.
By now, you have probably thought of an objection: isn't this approach wasteful? Isn't this going to search through the entire input list, when it only has to go as far as the first change of direction? Actually, no, it won't, because of lazy evaluation. In the example above, it calculated the entire comparisons list because it had to in order to print it out. But if it's going to pass the result to zigzag, it will only evaluate the comparisons list far enough to find one instance of GT and one of LT, and no further. To convince yourself of this, consider these cases:
> zigzag $ 2:[1..]
True
> zigzag 1:[9,8..]
True
The input in both cases is an infinite list ([2,1,2,3,4,5..] and [1,9,8,7,6,5...]). Try to print them out, and they will fill up the screen. But pass them to zigzag, and it will return very quickly, as soon as it finds the first change in direction.
A lot of the difficultly in reading code comes from following multiple branches of control flow. And a lot of those branches are really efforts to avoid calculating more than we need to. But much of the same thing can be achieved with lazy evaluation, allowing the program to be both shorter and truer to the original question.
Try this
(define sorted?
(lambda (l)
(cond ((null? l) #t)
(else (check-asc? (car l) (sorted? (cdr l))
(check-desc? (car l) (sorted? (cdr l))))))
(define check-asc?
(lambda (elt lst)
(cond ((null? lst) #t)
(else (or (< elt (car lst)) (= elt (car lst))) (check-asc? (car lst) (cdr lst))))))
(define check-desc?
(lambda (elt lst)
(cond ((null? lst) #t)
(else (or (< elt (car lst)) (= elt (car lst))) (check-desc? (car lst) (cdr lst))))))
I am a newbie myself. I haven't tested this code. Still struggling with recursion. Please tell me if it worked or what error it gave.
The previous answer i gave was really bad.
I ran the code in DrScheme and it gave errors.
However I have modified it. Here is a code that works:
(define sorted?
(lambda (l)
(cond ((null? l) #t)
(else (if (check-asc? (car l) (cdr l)) #t
(check-desc? (car l) (cdr l)))))))
(define check-asc?
(lambda (elt lst)
(cond ((null? lst) #t)
(else (if (or (< elt (car lst)) (= elt (car lst))) (check-asc? (car lst) (cdr lst))
#f)))))
(define check-desc?
(lambda (elt lst)
(cond ((null? lst) #t)
(else (if (or (> elt (car lst)) (= elt (car lst))) (check-desc? (car lst) (cdr lst))
#f)))))
Cases checked:
(sorted? '(5 4 3 2 1))
returns #t
(sorted? '(1 2 3 4 5))
returns #t
(sorted? '(1 2 3 5 4))
returns #f
(sorted? '())
returns #t
(sorted? '(1))
returns #t

How to get rid of duplicates in a list, but keep the order

I am using Intermediate Student with Lambda in DrRacket, I was wondering how one would remove the duplicates in a list, while keeping the order. For example (remove-dup (list 2 5 4 5 1 2)) would produce (list 2 5 4 1). So far, I have this:
(define (remove-duplicates lst)
(cond
[(empty? lst) empty]
[(member? (first lst) (rest lst))
(remove-duplicates (rest lst))]
[else (cons (first lst) (remove-duplicates (rest lst)))]))
, but there's a problem since it doesn't keep the order. Can someone point me in the right direction? Thanks for your time.
If your goal is to get the functionality working, and not some homework question, then you don't need to do anything, just use remove-duplicates:
Welcome to Racket v5.2.
-> (remove-duplicates (list 2 5 4 5 1 2))
'(2 5 4 1)
This is the solution:
(define (remove-duplicates lon)
(foldr (lambda (x y) (cons x (filter (lambda (z) (not (= x z))) y))) empty lon))
Old question, but this is an implementation of J-Y's idea.
(define (dup-rem lst)
(cond
[(empty? lst) empty]
[else (cons (first lst) (dup-rem (filter (lambda (x) (not (equal? (first lst) x))) lst)))]))
SRFI-1 has delete-duplicates, although it's inefficient. (I am not too familiar with Racket, but surely it has SRFI-1, and the source...)
http://srfi.schemers.org/srfi-1/srfi-1.html#delete-duplicates
Run through the list sequentially, inserting each element in a hash table or other dictionary. If you try to insert an element that is already in the hash table, do not add it to the outgoing list.
What you need to do is compare in reverse order the entire time. You can use the reverse function which returns a list in reverse order. That way you are always removing the 2nd+ occurrence of an element and not the first. Here is an example, however it is using let and if and not a cond expression.
http://www.cs.bgu.ac.il/~elhadad/scheme/duplicates.html
Good luck with your homework :)
hmm i just had a racket exam recently, :/
the 'standard' remove-duplicates works fine but i was using pretty-big in drRacket so it had to be loaded using (require racket/list)
here is an alternative way :)
using mutation (not really in the spirit of racket but.. it works.)
(define (set l)
(define the-set '())
(begin (for-each
(lambda (x)
(if (member x the-set)
#t
(set! the-set (cons x the-set))))
l)
(reverse the-set)))
hope this helps... cheers!
I'm not sure if this is homework, but in case it is I'll post just the idea. If it's not tell me and I can put a solution here.
What you need is to keep track of the unique items you find, you can do that by using an auxiliary list, like an accumulator, to keep track of the ones you found so far.
Whenever you look at another item check to see if it's in the auxiliary list. In case it's not add it to the auxiliary list.
You'll end up with a reverse order of what you're trying to find, so you can just (reverse ...) it and you'll have your answer.

Python's Reduce Function - Written in Scheme

Evening!
I need to write a reduce function in Scheme that works just as the built-in reduce function in Python. It's easy to write a reduce function in Scheme:
(define (reduce fn lis identity)
(if (null? lis)
identity
(fn (car lis)
(reduce fn (cdr lis) identity))))
However, this code isn't identical to the Python reduce, which takes only two arguments (the function and a list of items to reduce).
Can anyone help me write a Scheme function that works this way?
(>(reduce * '(2 4 5 5)) => 200, is our professor's example.)
Thanks so much, guys and gals. You are so helpful <3
ETA: To Mr. Levien and Mr. Jester-Young, thank you so very much. You provided the perfect amount of information to help me figure the problem out on my own. *hug
That is easy. The accumulator is initialized with the first element of the list:
(define (py-reduce f ls) (fold f (car ls) (cdr ls)))
(py-reduce * '(2 4 5 5)) => 200
Feel free to use another reduce function than fold from srfi-1 (like reduce, fold-right ...) or use your own. Your list needs one element at least.
Having an identity allows your function to work with a list of size zero or more - when it's an empty list, you get the identity. Without an identity, the function will only work with a list of one or more elements. Some functions naturally have an identity (zero for addition, one for multiplication, etc). Others don't - min and max in particular, especially over big ints.
You should be able to figure out the rest :)
Below is a tail-recursive version. Your professor isn't likely to like it (since it doesn't demonstrate recursion ;-)), but at least it will give you some idea how to go about it.
(define (reduce func lst)
(let loop ((val (car lst))
(lst (cdr lst)))
(if (null? lst) val
(loop (func val (car lst)) (cdr lst)))))
As hinted in Raph Levien's excellent answer, this version will not work if the incoming list is empty (that'd be what the identity parameter is for). You will, in this case, get an error (since you can't car or cdr an empty list).

Resources