In Scheme, you define functions like
(define f (lambda (x) ...))
In particular, you can do something like this
(define f (g))
where g is some function returning a function. Is it possible to do the same in Common Lisp, i.e. to associate a function symbol with a given anonymous function?
Nevermind, I just found the answer in Paul Graham's book ANSI Common Lisp (after looking the second time; p. 99):
(setf (symbol-function 'f) (lambda (x) (* x x)))
achieves (for most intents and purposes) the same as
(defun f (x) (* x x))
Related
Is Scheme's letrec only meant for defining procedures, especially recursive ones? I am asking because it appears to be possible to bind non-procedures using letrec. For example, (letrec ((x 1) (y 2)) (+ x y)). If Scheme's letrec is only meant for procedures, then why isn't its syntax constrained to allow procedures only?
Consider this use of letrec to define two mutually recursive procedures:
(letrec ((is-even? (lambda (n)
(let ((n (abs n)))
(if (= n 0)
#t
(is-odd? (- n 1))))))
(is-odd? (lambda (n)
(let ((n (abs n)))
(if (= n 0)
#f
(is-even? (- n 1)))))))
(is-even? 123))
If we use Common Lisp's LABELS instead of Scheme's letrec, these two mutually recursive procedures would be defined like this instead:
(labels ((even-p (n)
(let ((n (abs n)))
(if (= n 0)
t
(odd-p (- n 1)))))
(odd-p (n)
(let ((n (abs n)))
(if (= n 0)
nil
(even-p (- n 1))))))
(even-p 123))
If letrec is only useful for defining procedures, then why isn't its syntax constrained like that of LABELS to allow only procedures in its initialization forms?
It is mostly useful for binding procedures, yes: the variables bound by letrec can't refer to their own bindings until afterwards, so something like
(letrec ((x (list x)))
x)
Does not work: see my other answer.
However first of all it would be a strange restriction, in a Lisp-1 like Scheme, to insist that letrec can only be used for procedures. It's also not enforcable other than dynamically:
(letrec ((x (if <something>
(λ ... (x ...))
1)))
...)
More importantly, letrec can be used in places like this:
(letrec ((x (cons 1 (delay x))))
...)
which is fine, because the reference to the binding of x is delayed. So if you have streams, you can then do this:
;;; For Racket
(require racket/stream)
(letrec ((ones (stream-cons 1 ones)))
(stream-ref ones 100))
It is useful for defining procedures, but it is not only for that.
The difference between let* and letrec is defined in the manual:
Like let, including left-to-right evaluation of the val-exprs, but the locations for all ids are created first, all ids are bound in all val-exprs as well as the bodys, and each id is initialized immediately after the corresponding val-expr is evaluated.
The order in which ids are bound is significant here, as let* would not be useful for defining mutually-recursive procedures: the first procedure would have an unbound id for the second procedure.
As your example comes directly from the manual I think you should see that CS information is often dense and terse when reading, but it does say very clearly what the difference is with letrec.
I am trying to define a function func->symbol that takes a function and returns its name as a symbol. For example:
(define (pythagoras a b)
(sqrt (+ (* a a) (* b b))))
;; #1
(func->symbol pythagoras) ; Returns: 'pythagoras
;; #2
(func->symbol (if #t pythagoras sqrt)) ; Returns: 'pythagoras
;; #3
(let ((f (if #t pythagoras sqrt)))
(func->symbol f)) ; Returns: 'pythagoras
;; #4
(let ((f (if #t pythagoras sqrt)))
(let ((g f))
(func->symbol g))) ; Returns: 'pythagoras
This is a follow-up question on How do I get a definition's name as a symbol? which only deals with case #1. For case #1, a simple macro def->symbol is sufficient:
(define-syntax def->symbol
(syntax-rules ()
((_ def) 'def)))
However, this macro definition does not pass cases #2, #3, #4. Is it possible to define func->symbol, or is Scheme not expressive enough for this?
In Racket, in many cases, you can get a function's name using object-name. But it is probably a bad idea to rely on this result for anything other than debugging.
Perhaps it's worth an answer which shows why this is not possible in any language with first-class functions.
I'll define what I mean by a language having first-class functions (there are varying definitions).
Functions can be passed as arguments to other functions, and returned as values from them.
Functions can be stored in variables and other data structures.
There are anonymous functions, or function literals.
Scheme clearly has first-class functions in this sense. Now consider this code:
(define a #f)
(define b #f)
(let ((f (lambda (x)
(+ x 1))))
(set! a f)
(set! b f))
Let's imagine there is a function-name function, which, given a function, returns its name. What should (function-name a) return?
Well, the answer is that there's simply no useful value it can return (in Racket, (object-name a) returns f, but that's clearly exposing implementation details which might be useful for debugging but would be very misleading as a return value for a function-name procedure.
This is why such a procedure can't exist in general in a language with first-class functions: the function which maps from names to values is many-to-one and thus has no inverse.
Here is an example of the sort of disgusting hack you could do to make this 'work' and also why it's horrible. The following is Racket-specific code:
(define-syntax define/naming
;; Define something in such a way that, if it's a procedure,
;; it gets the right name. This is a horrid hack.
(syntax-rules ()
[(_ (p arg ...) form ...)
(define (p arg ...) form ...)]
[(_ name val)
(define name (let ([p val])
(if (procedure? p)
(procedure-rename p 'name)
p)))]))
And now, given
(define/naming a
(let ([c 0])
(thunk
(begin0
c
(set! c (+ c 1))))))
(define/naming b a)
Then:
> (object-name a)
'a
> (object-name b)
'b
> (eqv? a b)
#f
> (a)
0
> (b)
1
> (a)
2
So a and b have the 'right' names, but because of that they are necessarily not the same object, which I think is semantically wrong: if I see (define a b) then I want (eqv? a b) to be true, I think. But a and b do capture the same lexical state, so that works, at least.
Is there a simpler way to achieve threading functionality in racket? I know about the threading library but it seems like such a basic functionality that I wonder if there is not some builtin way to do this.
(define (thread x . fns)
(foldl (lambda (f a) (f a))
thread
fns))
Also, can you express (lambda (f a) (f a)) in a simpler fashion?
There are lots of ways of doing this. A nice one is to use a macro, a simple (and perhaps not completely correct) version of which is:
(define-syntax (/> stx)
(syntax-case stx ()
[(_ x)
#'x]
[(_ x f)
#'(f x)]
[(/> x f fs ...)
#'(/> (f x) fs ...)]
[/>
(identifier? #'/>)
#'(λ (x . fns)
(for/fold ([r x]) ([f fns])
(f r)))]))
Now, for instance (/> x sin cos) is expanded to (cos (sin x)): there is no run-time overhead at all. The last clause means that (apply /> 1 (list sin cos)) will work.
I'm not sure the above macro is completely correct, particularly the last clause.
I'm trying to understand the whole principal of church encoding through Scheme. I think I understand the basics of it such as
Church numeral for 0
(define c-0
(lambda (f)
(lambda (x)
x)))
Church numeral for 1
(define c-1
(lambda (f)
(lambda (x)
(f x))))
... and continue applying the function to x N times.
Now my problem is just what does this all mean? If I take church-3 for example:
(define c-3
(lambda (x)
(lambda (f)
(f (f (f x))))))
What is this actually doing? I have only basic scheme knowledge as well but I don't even understand how to use the function? what is an example input using the c-3 function? is it just applying something 3 times like a loop?
You are right. c-3 in this case is a function, that takes 1 argument. And returns another function.
This other function takes a 1 argument function, and applies it to the first argument.
In this example, I'm calling c-3 with an argument of 3, this will return a function.
Then, I feed this function, another function, that add1 to x.
((c-3 3) (lambda (x) (add1 x)))
6
This will produce 6 as you see. It applies add1 to 3, 3 times. I know this is confusing. But you can
manually replace the arguments in the body of the function to understand it better. Wherever you see f, just replace that with (lambda (x) (add1 x)) And replace x with 3 (or any number).
This will work with any 1 argument function as long as the argument is of the correct type.
Consider the following code:
(call-with-values
(lambda ()
(call/cc (lambda (k)
(k k k))))
(lambda (x y)
(procedure-arity y)))
It's pretty obvious here that the continuation at the point of the call/cc call is the lambda on the right-hand side, so its arity should be 2. However, the return value of the above (in Racket) is (arity-at-least 0) instead.
Indeed, running similar code in Guile (substituting procedure-minimum-arity for procedure-arity) shows that the continuation also supposedly allows any number of arguments, even though it's pretty clearly not the case.
So, why is that? As far as I understand (correct me if my understanding is wrong), the arity of a continuation is pretty straightforward: it's 1 except in the context of call-with-values, in which case it's whatever the arity of the right-hand-side lambda is. (Which, granted, can be complicated if it's a case-lambda or the like, but no more complicated than if you were calling (procedure-arity (case-lambda ...)) directly.)
A simpler way to see the same is:
(call-with-values
(lambda () (error 'arity "~v" (procedure-arity (call/cc (λ (k) k)))))
(lambda (x y) (procedure-arity y)))
and even simpler:
(procedure-arity (call/cc (λ (x) x)))
And for your question -- it's clear in the first case that the continuation expects two inputs, but cases like that are not too common. Eg, they're usually such examples, whereas "real code" would use define-values or have some unknown continuation, where the continuations that call/cc creates can have different arities depending on the context that they were created at. This means that there's not much point in trying to figure out these rare cases where the continuation's arity is known.
Footnote:
;; nonsensical, but shows the point
(define (foo) (call/cc (λ (x) x)))
(define x (foo))
(define-values [y z] (foo))