scheme higher order func - hash

Given the skeleton of a function:
(define gen-hash-division-method (lambda (size)))
as well as:
(define hash-1 (gen-hash-division-method 701))
What I have coded:
(define gen-hash-division-method
(lambda (size)
(lambda (w)
(modulo key(flip(w)) size))))
key(flip(w)) takes a list w and returns an integer.
And call:
(hash-1 '(h e l l o))
I keep getting this error:
procedure application: expected procedure, given: (h e l l o) (no arguments)

You're getting the error because in Scheme (w) expects w to be a function. But w is just a list of symbols.
In your case you have key(flip(w)) which doesn't make sense in Scheme land.
everything is surrounded by parentheses
You want (key (flip w))
Remember the lisp mantra : (function args ...)

Related

The Little Typer. I don't understand the meaning of The Initial Second Commandment of λ

I have tried following examples, but no matter y occurred or not,
The function f returns the same value as (λ(y)(f y)) after application.
I would like to do is to define a function that is not the same (-> Y X) as (λ (y)(f y)) when y occurred in y as a counter example, but I don't know how.
Do I misunderstand the meaning of The Initial Second Commandment of λ?
;;y does not occurs
(claim f (-> Nat Nat))
(define f
(λ(y)
0))
;; both return (the Nat 0)
(f 5)
((the (-> Nat Nat)
(λ(y)
(f y)))
5)
;; y occurs
(claim g (-> Nat Nat))
(define g
(λ(y)
y))
;;both return (the Nat 5)
(g 5)
((the (-> Nat Nat)
(λ(y)
(g y)))
5)
In order to create an example illustrating the importance of the caveat "...as long as y does not occur in f", we need to create a function f in which a name y occurs free. The provision that y is free in f is critical. This is also why it is difficult to create such an example: (top-level) functions cannot contain free variables. However, functions that are interior to other functions can. This is the key.
Here is function g that contains another function inside of it:
(claim g (-> Nat
(-> Nat
Nat)))
(define g
(lambda (y)
(lambda (x) ;; Call this inner
y))) ;; function "f"
(I've chosen to write the claim in this way to emphasize that we are thinking about a function inside of a function.)
To get our bearings, this simple function g expects two Nat arguments, and returns the first.
Let's call the inner function f. Note that f contains a free variable y (for this reason, f is meaningless outside of g). Let's substitute (lambda (y) (f y)) for f:
(claim g1 (-> Nat
(-> Nat
Nat)))
(define g1
(lambda (y)
(lambda (y) ;; Here we've replaced "f"
((lambda (x) ;; with an eta-expanded
y) ;; version, introducing
y)))) ;; the name "y"
We can eliminate the application to produce the following expression:
g1
---------------- SAME AS
(lambda (y)
(lambda (y)
((lambda (x)
y)
y)))
---------------- SAME AS
(lambda (y)
(lambda (y)
y))
---------------- SAME AS
(lambda (y)
(lambda (y1)
y1))
In the last step, I've renamed the second y to y1 to illustrate that the variable in the body of the inner function refers to the closer binding site, and not the farther one.
To recap, we started with a function g that "takes two (curried) arguments and returns the first". We then introduced a faulty eta-expansion around the inner function. As a result, we ended up with a function g1 that "takes two (curried) arguments and returns the second". Clearly not equivalent to the original function g.
So this commandment is about variable capture, which is the price we pay for working with names. I hope that helps!
IMPORTANT NOTE:
Due to the way that Pie checks types, you will need to introduce an annotation in the body of g if you want to try this example out:
(claim g1 (-> Nat
(-> Nat
Nat)))
(define g1
(lambda (y)
(lambda (y)
((the (-> Nat Nat)
(lambda (x)
y))
y))))

What does the expression (define (f x) (length (range 3000))) evaluate to?

For the expression
(define x (length (range 3000)))
I think it is evaluated to
(define x 3000)
For the expression
(define (f x) (length (range 3000)))
Does it evaluate to the following as well?
(define (f x) 3000)
No, they evaluate to two different procedures, with different bodies. A completely different matter is that when executed, they both will return the same value, namely 3000, ignoring the parameter in both cases. To be clear, the first expression binds f to a lambda (this is how define expands a procedure definition under the hood):
(define f
(lambda (x) (length (range 3000))))
The second expression also binds f to a lambda, but it's a different one:
(define f
(lambda (x) 3000))
Either one will return 3000 when invoked:
(f 42)
=> 3000
But the first one will do more work, it has to create a range and calculate its length, whereas the second one simply returns 3000. Regarding your first example - in the end x will have the same value, and it won't matter how you calculated it. But for the second example, the two fs are different objects, even though the values they calculate are the same.

Occurrence typing with polymorphic union types

Suppose I want to convert the following untyped code into typed racket. These functions are inspired by SICP where they show how a data structure can be constructed purely from functions.
(define (make-pair x y)
(lambda (c)
(cond
((= c 1) x)
((= c 2) y)
(error "error in input, should be 1 or 2"))))
(define (first p) (p 1))
(define (second p) (p 2))
To convert it straight to typed racket, the return value of the make-pair function seems to be (: make-pair (All (A B) (-> A B (-> Number (U A B))))). And following this, the type of first should be (: first (All (A B) (-> (-> Number (U A B)) A))). However, while implementing the function we can't call (p 1) directly now because we need some sort of occurrence typing to make sure first returns only of type A. Changing the return type of first to (U A B) works but then the burden of occurrence typing goes on the user and not in the API. So in this scenario how can we use occurrence typing inside first (that is, how to use a predicate for type variable A) so that we can safely return only the first component of the pair?
UPDATE
I tried an approach which differs a bit from above and requires the predicates for A and B to be supplied as arguments to make-pair function. Below is the code:
#lang typed/racket
(define-type FuncPair (All (A B) (List (-> Number (U A B)) (-> A Boolean) (-> B Boolean))))
(: make-pair (All (A B) (-> A B (-> A Boolean) (-> B Boolean) (FuncPair A B))))
(define (make-pair x y x-pred y-pred)
(list
(lambda ([c : Number])
(cond
((= c 1) x)
((= c 2) y)
(else (error "Wrong input!"))))
x-pred
y-pred))
(: first (All (A B) (-> (FuncPair A B) Any)))
(define (first p)
(let ([pair-fn (car p)]
[fn-pred (cadr p)])
(let ([f-value (pair-fn 1)])
(if (fn-pred f-value)
f-value
(error "Cannot get first value in pair")))))
However, this fails in the check (fn-pred f-value) condition with error expected: A
given: (U A B) in: f-value
From the untyped code at the start of your question, it seems like a pair of A and B is a function that given 1, gives back A, and given 2, gives back B. The way to express this type of function is with a case-> type:
#lang typed/racket
(define-type (Pairof A B)
(case-> [1 -> A] [2 -> B]))
The accessors can be defined the same way as your original untyped code, just by adding type annotations:
(: first : (All (A B) [(Pairof A B) -> A]))
(define (first p) (p 1))
(: second : (All (A B) [(Pairof A B) -> B]))
(define (second p) (p (ann 2 : 2)))
The type of the constructor should be:
(: make-pair : (All (A B) [A B -> (Pairof A B)]))
But the constructor doesn't quite work as-is. One thing wrong with it is that your else clause is missing the else part of it. Fixing that gives you:
(: make-pair : (All (A B) [A B -> (Pairof A B)]))
(define (make-pair x y)
(lambda (c)
(cond
[(= c 1) x]
[(= c 2) y]
[else (error "error in input, should be 1 or 2")])))
This is almost right, and if typed racket were awesome enough, it would be. Typed racket treats equal? specially for occurrence typing, but it doesn't do the same thing for =. Changing = to equal? fixes it.
(: make-pair : (All (A B) [A B -> (Pairof A B)]))
(define (make-pair x y)
(lambda (c)
(cond
[(equal? c 1) x]
[(equal? c 2) y]
[else (error "error in input, should be 1 or 2")])))
Ideally occurrence typing should work with =, but perhaps the fact that things like (= 2 2.0) return true makes that both harder to implement and less useful.

Reverse list on top level without 'appent' or 'list'

I made some function that can reverse simple lists, like (q w e r t y)
By the task it should correctly process: empty lists, lists, pairs, improper lists.
But now it fails on improper lists, like (q w e r t . y) or pairs.
How to process this situations?
My code:
(define myInverse2
(lambda (original result)
(
cond ((null? original)
result )
(#t
(myInverse2 (cdr original) (cons (car original) result)) )
) ) )
And dr Racket output:
Your code fails because when original is not null?, you assume you can take the cdr of it, which is not always guaranteed. You could fix your code to distinguish between cons? values and other values.
But first, ask yourself if this is necessary and what would be the reverse of some of your inputs. The reverse of a simple pair (x . y) is (y . x).
But what about the reverse of
(q w e r t . y)? I would expect reverse be its own inverse function (i.e. involution), so that you always have:
(equal? x (reverse (reverse x)))
... and if the reverse of the above is (y t r e w q), then you lose this property. Or, you could chose to have the result be (y t r e w . q), which, when reversed, gives you your result back. That is why you first have to chose what is the meaning of your function. Then, if the above approach is the one you want to take, then change should be easy; e.g. add a case in your cond which matches (cons? original).

Typed Racket: Creating generic types with define-type

I'm trying to get a bit into Typed Racket, but I'm having some trouble getting an (admittedly rather constructed) experiment to work.
This is what I originally had:
#lang typed/racket
(: generate-list
(All (A)
((A -> A) (Integer -> A) Integer -> (Listof A))))
(define (generate-list function location-function num-items)
(let: loop : (Listof A)
((count : Integer 0)
(result : (Listof A) (list)))
(if (>= count num-items)
(reverse result)
(loop (+ count 1)
(cons (function (location-function count)) result)))))
; ---------------------------------
(: f (Number -> Number))
(define (f x) (* x x))
(: locf (Integer -> Number))
(define (locf x) x)
; ---------------------------------
(displayln (generate-list f locf 10))
Which has the output:
(0 1 4 9 16 25 36 49 64 81)
Which is nice. Then I figured I could make this a bit better documented by giving the function and location-function a defined type:
#lang typed/racket
(define-type (ListGenFunction A) (A -> A))
(define-type (ListGenLocFunction A) (Integer -> A))
(: generate-list
(All (A)
(ListGenFunction ListGenLocFunction Integer -> (Listof A))))
(define (generate-list function location-function num-items)
(let: loop : (Listof A)
((count : Integer 0)
(result : (Listof A) (list)))
(if (>= count num-items)
(reverse result)
(loop (+ count 1)
(cons (function (location-function count)) result)))))
; ----------- Numbers! ------------
(: f ListGenFunction)
(define (f x) (* x x))
(: locf ListGenLocFunction)
(define (locf x) x)
; ---------------------------------
(displayln (generate-list f locf 10))
Now here's where the problems start (and I really hope some experienced Typed Racketeers aren't facepalming too hard right now). For one, the type checker gives me an error on the line where I define f. The message is rather lengthy, but it's basically: "Type Checker: No function domains matched in function application: Types: ... in: (* x x)". I thought I defined a type that has one parameter of a generic type A that returns a generic type A? Wouldn't (* x x) work? Or is there some need to "tag" the type? (Like in C++-like languages where it's list<int> for example)
On top of that: Now my type-definition for the function generate-list has a return type of "(Listof A)". But that A is not at all declared to be the same A that the parameters with the types ListGenFunction and ListGenLocFunction expect. I kind of want to make that connection, however, so that anyone who uses that function can be sure that the types of his provided functions match the type of the returning list items.
How do I do this correctly?
PS:
I'm not sure if I described my intention in the last paragraph so that anyone can understand it. But if you take some generic pseudo-C++-like code, I want to get the following:
list<T> generate-list(LGF<T> f, LGLF<T> locf, int count) { ... }
So that all T's are exactly the same.
There are two problems here, both of which stem from the same confusion. You're using a generic type, ListGenFunction, without telling Typed Racket (or the reader of your program) what particular type you're using it with.
For example, f isn't an arbitrary ListGenFunction, it's a ListGenFunction that works specifically on numbers. So you should write:
(: f (ListGenFunction Integer))
and
(: locf (ListGenLocFunction Integer))
Similarly, you should give generate-list a type like this:
(: generate-list
(All (A)
((ListGenFunction A) (ListGenLocFunction A) Integer -> (Listof A))))
This is just like how you explicitly say that you're producing a (Listof A), not just a Listof.