According to my assignment, some of the values defined below in Scheme-notation are functions. I need to determine the value if it is not a function. Otherwise, I have to determine what the function calculates.:
First: (define res (+ 1 1))
Second: (define res2 ((lambda (i) (* wert1 i)) 2))
Now as far as I am concerned, the + is the functions name and the values 1,1 are the parameters of the function. Same for the seconds case. Lambda is a way to write functions in Scheme, isn't it? So I thought this must be a function too.
My solutions says that both are not functions but values!
Did I get something wrong or do my solutions have a twist?
You're right that + and (lambda (i) ...) are functions. However that wasn't the question. The question was whether the defined values (i.e. res and res2) are functions.
res is defined to be equal to (+ 1 1), which calls the + function with the arguments 1 1 (just as you said). The result of doing that is 2. So res is equal to 2, which is a number, not a function.
The same is true for the definition of res2: (lambda (i) (* wert1 i)) is a function. But you're not defining res2 to be equal to (lambda (i) (* wert1 i))1, you're defining it to be equal to the result of applying that function to the argument 2. So you're supposed to answer what the result of applying that function to that argument is.
1 That would look like this:
(define res3 (lambda (i) (* wert1 i)))
And in that case, "res3 is a function" would be the correct answer.
Related
I'm currently revising the chapter for the lambda (\) expressions in Haskell. Was just wondering if someone could please help explain how did this:
const :: a → b → a
const x _ = x (this part)
Get defined into this:
const :: a → (b → a)
const x = λ_ → x (how did it become like this?)
The signatures a -> b -> a and a -> (b -> a) are parsed exactly the same, much like the arithmetic expressions 1 - 2 - 3 and (1 - 2) - 3 are the same: the -> operator is right-associative, whereas the - operator is left associative, i.e. the parser effectively puts the parentheses in the right place if not explicitly specified. In other words, A -> B -> C is defined to be A -> (B -> C).
If we explicitly write a -> (b -> a), then we do this to put focus on the fact that we're dealing with curried functions, i.e. that we can accept the arguments one-by-one instead of all at once, but all multi-parameter functions in Haskell are curried anyway.
As for why const x _ = x and const x = \_ -> x are equivalent: well first, to be pedantic they're not equivalent, see bottom of this answer. But let's ignore that for now.
Both lambdas and (single) function clauses are just ways to define functions. Like,
sqPl1 :: Int -> Int
sqPl1 x = x^2 + 1
does the same as
sqPl1 = \x -> x^2 + 1
It's just a different syntax. Some would say the f x = ... notation is just syntactic sugar for binding x in a lambda, i.e. f = \x -> ..., because Haskell is based on lambda calculus and in lambda calculus lambdas are the only way to write functions. (That's a bit of an oversimplification though.)
I said they're not quite equivalent. I'm referring to two things here:
You can have local definitions whose scope outlasts a parameter binding. For example if I write
foo x y = ec * y
where ec = {- expensive computation depending on `x` -}
then ec will always be computed from scratch whenever foo is applied. However, if I write it as
foo x = \y -> ec * y
where ec = {- expensive computation depending on `x` -}
then I can partially apply foo to one argument, and the resulting single-argument function can be evaluated with many different y values without needing to compute ec again. For example map (foo 3) [0..90] would be faster with the lambda definition. (On the flip side, if the stored value takes up a lot of memory it may be preferrable to not keep it around; it depends.)
Haskell has a notion of constant applicative forms. It's a subtle topic that I won't go into here, but that can be affected by whether you write a function as a lambda or with clauses or expand arguments.
The Common Lisp case macro always defaults to eql for testing whether its keyform matches one of the keys in its clauses. I'm aiming with the following macro to generalize case to use any supplied comparison function (although with evaluated keys):
(defmacro case-test (form test &rest clauses)
(once-only (form test)
`(cond ,#(mapcar #'(lambda (clause)
`((funcall ,test ,form ,(car clause))
,#(cdr clause)))
`,clauses))))
using
(defmacro once-only ((&rest names) &body body)
"Ensures macro arguments only evaluate once and in order.
Wrap around a backquoted macro expansion."
(let ((gensyms (loop for nil in names collect (gensym))))
`(let (,#(loop for g in gensyms collect `(,g (gensym))))
`(let (,,#(loop for g in gensyms for n in names collect ``(,,g ,,n)))
,(let (,#(loop for n in names for g in gensyms collect `(,n ,g)))
,#body)))))
For example:
(macroexpand '(case-test (list 3 4) #'equal
('(1 2) 'a 'b)
('(3 4) 'c 'd)))
gives
(LET ((#:G527 (LIST 3 4)) (#:G528 #'EQUAL))
(COND ((FUNCALL #:G528 #:G527 '(1 2)) 'A 'B)
((FUNCALL #:G528 #:G527 '(3 4)) 'C 'D)))
Is it necessary to worry about macro variable capture for a functional argument (like #'equal)? Can such arguments be left off the once-only list, or could there still be a potential conflict if #'equal were part of the keyform as well. Paul Graham in his book On Lisp, p.118, says some variable capture conflicts lead to "extremely subtle bugs", leading one to believe it might be better to (gensym) everything.
Is it more flexible to pass in a test name (like equal) instead of a function object (like #'equal)? It looks like you could then put the name directly in function call position (instead of using funcall), and allow macros and special forms as well as functions?
Could case-test instead be a function, instead of a macro?
Variable capture
Yes, you need to put the function into the once-only because it can be created dynamically.
The extreme case would be:
(defun random-test ()
(aref #(#'eq #'eql #'equal #'equalp) (random 4)))
(case-test foo (random-test)
...)
You want to make sure that the test is the same in the whole case-test form.
Name vs. object
Evaluating the test argument allows for very flexible forms like
(case-test foo (object-test foo)
...)
which allows "object-oriented" case-test.
Function vs. macro
Making case-test into a function is akin to making any other conditional (if and cond) into a function - how would you handle the proverbial
(case-test "a" #'string-equal
("A" (print "safe"))
("b" (launch missiles)))
There seems to be a number of different ways of referring to a function in Common Lisp:
via symbol, where the symbol appears (unquoted) as the car of a form as in (1+ 2) => 3, or in a functional argument position as in (mapcar '1+ '(1 2 3)) => (2 3 4);
via function object, where the (interpreted or compiled) function object can appear in functional argument position as in (mapcar #'1+ '(1 2 3)) => (2 3 4) or (mapcar (symbol-function '1+) '(1 2 3)) => (2 3 4), but not as the car of a form as in (#'1+ 2) => error or ((symbol-function '1+) 2) => error;
via lambda expression, where the lambda expression appears as the car of a lambda form as in ((lambda (x) (1+ x)) 2) => 3, or in a functional argument position as in (mapcar (lambda (x) (1+ x)) '(1 2 3)) => (2 3 4) [However, the Hyperspec does not recognize lambda expression as a "function designator"].
Of these three "ways", to me the first seems somewhat out of place, because it seems to complicate the fundamental guideline that Common Lisp operators evaluate their arguments only once. And if, in the example above, '1+ is evaluated, it would produce the symbol 1+, not the function named by the symbol. In this case, there must be an additional evaluation, possibly symbol-function, to get at the function object. Evidently, this is simply a convenience, but it seems to break with consistency. (The consistent form #'1+ is almost as simple.) My question is 'Are there any examples where using a symbol for a function is required (other than as the car of a form--although even this is not required, given lambda expressions), so that you cannot fully avoid expressions as in item 1 above?.
Symbols as names for objects: Designators
Often symbols are names for objects and can be used instead of these objects.
The concept that something like a symbol (or a string, a character) may stand for something else is called in Common Lisp a designator.
Some example for designators:
Function designator:
(funcall 'list 1 2 3)
<->
(funcall (symbol-function 'list) 1 2 3)
Class, or symbol that names a class:
(make-instance 'my-class)
<->
(make-instance (find-class 'my-class))
Package designator:
(package-use-list 'cl-user)
<->
(package-use-list (find-package 'cl-user))
<->
(package-use-list "CL-USER")
String designator:
(string-upcase 'f)
<->
(string-upcase (symbol-name 'f))
<->
(string-upcase #\f)
The first argument to FUNCALL thus is not defined as a function, but as a function designator. In this case either a function object or a symbol. If it is a symbol, then the global symbol function is retrieved.
Historically Lisp uses symbols as names for various kinds of objects. This is less prominent in some later dialects or derived languages.
function object vs. calling a named function vs. calling a symbol function
...(funcall (function foo) 1 2 3)...
...(funcall #'foo 1 2 3)...
Above calls the lexical function named foo. If there is no lexical function foo, it calls the symbol function of foo. The Lisp file compiler may assume that this is the same named function in the same file.
...(foo 1 2 3)...
Above calls the lexical function named foo. If there is no lexical function foo, it calls the symbol function of foo. The Lisp file compiler may assume that this is the same named function in the same file.
...(funcall 'foo 1 2 3)...
Above calls the global symbol function of foo. Thus there will be a lookup through the symbol.
Suppose I have a series of functions with keyword arguments of different names
foo(x, y; a=1, b=2) = (a + b) / (x + y)
bar(x, y; c=3, d=4) = (x - y) * (c - d)
And suppose I have third function that takes a function as an argument. I want to be able to pass any keyword argument(s) through to one of the first two functions when calling this third function.
master(x, y; fun::Function=foo, args...) = fun(x, y, args...)
My problem arises when trying to call the master function using keyword arguments.
julia> master(pi, e, fun=bar)
-0.423310825130748
julia> master(pi, e, fun=bar, c=4)
ERROR: MethodError: `bar` has no method matching bar(::Irrational{:π}, ::Irrational{:e}, ::Tuple{Symbol,Int64})
Closest candidates are:
bar(::Any, ::Any)
Is there a way to pass through the keyword arguments without having to iteratively check the argument names?
Please let me know if the question is unclear and I'd be happy to clarify. I've looked for other questions, but the solutions I've seen generally show how to grab the name-value pairs, not how to pass them through to other functions with keyword arguments
To highlight the answer spencerlyon2 gave in his comment, my problem was using a comma (,) instead of a semicolon (;) to separate the keyword arguments when calling fun.
WRONG:
master(x, y; fun::Function=foo, args...) = fun(x, y, args...)
RIGHT:
master(x, y; fun::Function=foo, args...) = fun(x, y; args...)
OK, it's been a long day and my brain may not function at Haskell level, but I just cannot understand one example from 'Learn You a Haskell'.
The section is called Function Application with $, and there is example of how $ may be defined:
($) :: (a -> b) -> a -> b
f $ x = f x
So far everything is clear. I understand all examples in the section, except for the last one:
ghci> map ($ 3) [(4+), (10*), (^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772]
Here we map ($ 3) across list of functions and get result of application of those functions to 3. But how is this possible?
From the first code snippet it's clear that first argument is a function, we can even write:
*Main> ($) sqrt 4
2.0
Now ($ 3) is a partial application of function $, but 3 goes on function's position! So 3 is supposed to be a function or what?
There is another mystery: what the heck is (4+)? I know that (+4) is a partial application of function +, so (4+) should be partial application of function 4? Nonsense. What sort of trick works here?
($ 3) and (+ 4) aren't partial applications - they're operator sections. A partial application would look like (($) 3) or ((+) 4).
An operator section of the form (? x) (where ? stands for an arbitrary infix operator) binds the right operand of the operator, i.e. it is equivalent to \y -> y ? x. Likewise the operator section (x ?) binds the left operand and is thus equivalent to partial application.
I think what's tripping you up is operator sections. These let you partially apply an operator with either one of its arguments, so you can have the operators (+4) and (4+), where 4 is the the second then the first argument to + respectively. A more clear example might be ("Hello" ++) versus (++ "world"), the former prepends "Hello" onto the front of a string, while the latter appends "world" onto the end of a string.
This is contrasted with using operators in prefix form with just parens around it. In this form, the following are equivalent:
> let join = (++)
> join "Hello, " "world"
"Hello, world"
> (++) "Hello, " "world"
"Hello, world"
In prefix form, you treat the operator as a normal function and it accepts its first then second argument in order. In operator sections, it matters which side of the operator the argument is on.
So in your example, you have the partial application of ($ 3), you can reduce it as
map ($ 3) [(4+), (10*), (^2), sqrt]
[($ 3) (4+), ($ 3) (10 *), ($ 3) (^ 2), ($ 3) sqrt]
[4 + 3, 10 * 3, 3 ^ 2, sqrt 3]
[7.0, 30.0, 9.0, 1.7320508075688772]
You are getting confused with sections. A good way to grasp the concept of sections is playing with an example:
(<^>) :: Int -> Float -> Int
a <^> b = a
The above function is an useless function which returns the first parameter no matter what the second parameter is. But it accepts Int and then Float as input.
Now, because of sections you can apply with any one of their arguments:
λ> let a = (3 <^>)
λ> :t a
a :: Float -> Int
λ> let b = (<^> 3.0)
λ> :t b
b :: Int -> Int
See how the type of a and b are different because of sections.