common lisp invoking function without apply leads to odd number of keywords - arguments

i am currently learning common lisp and stumbled upon a question i could not
answer my self:
(defun find-all (item seq &rest keyword-args &key (test #'eql)
test-not &allow-other-keys)
(if test-not
(apply #'remove item seq
:test-not (complement test-not) keyword-args)
(apply #'remove item seq
:test (complement test) keyword-args)))
The function is used to find every element in seq matching item according
to a test function.
Sadly I dont understand why the function 'apply' was used here.
Shouldn't it be possible to just invoke remove without apply?
A warnings says: "The function has an odd number of arguments in the keyword portion" if I invoke remove without apply.
I hope you can help me,
Thanks in advance!

REMOVE and FIND-ALL
REMOVE takes a bunch of keyword arguments: from-end, test, test-not, start, end, count and key.
Now in the function FIND-ALL you want to modify just one: either test or test-not and then call REMOVE.
How to write the parameter list of FIND-ALL
Now you have basically three options to write the parameter list of FIND-ALL, since it is basically the same as REMOVE with only one argument changed.
list every keyword argument with their defaults and later pass them on with the necessary changed to REMOVE.
list only a rest arguments list, manipulate this argument list and pass the new one via APPLY to REMOVE.
mix of 1. and 2. like in the example above. List only the required arguments and the keyword arguments to modify plus a rest list of the other keyword arguments provided at call time. Call REMOVE via APPLY.
How good are the three possibilities?
Now 1. has the advantage that you get to see a full parameter list for FIND-ALL and that it does not need to cons an argument list. Lisp can check some of that. But you really need to copy all arguments in your parameter list and later in the calls to REMOVE. Possible but not that great.
Then 2. has the disadvantage of not having a visible parameter list for FIND-ALL, but it might be easier to write with a few functions to manipulate argument lists. 3. is relatively easy to write, but also lacks the full parameter list.
Your example
Thus in your example it is version 3 of above:
the required arguments are passed in first
next are the modified arguments
last is the list of all keyword arguments
If you want to pass an existing list of arguments as part of the arguments to the function, then you need APPLY. That's why it is used there. APPLY calls a function with the arguments taken from a list.
CL-USER 1 > (apply #'+ 1 2 '(3 4 5))
15
CL-USER 2 > (let ((numbers '(3 4 5)))
(apply #'+ 1 2 numbers))
15
CL-USER 3 > (+ 1 2 3 4 5)
15

Let's take for example the signature of REMOVE:
remove item sequence &key from-end test test-not start end count key
=> result-sequence
The above means the function accepts 2 mandatory arguments, item and sequence, and additional keywords arguments that should be given with the :key value syntax. If you only give the key or the value, like:
(remove x list :count)
Then it is invalid. A simple test is to look at the number of parameters in keyword position and check that the number of given arguments is even. When it is odd, you know something is wrong.
If you call:
(remove item seq args)
You are in the same case. It does not matter that args is a list in your specific case.
Apply
APPLY is a more generic way of calling a function: its last argument is a list of additional arguments.
Suppose args is bound to (3 4), then:
(apply #'+ 1 args)
is equivalent to:
(+ 1 3 4)
This works with keyword arguments too; if args is the list (:count 1), then:
(apply #'remove item seq args)
is equivalent to:
(remove item seq :count 1)
And here, the number of arguments in keyword position is even.

Related

Scheme Language: +: contract violation, expected: number? [duplicate]

I know that you can use ' (aka quote) to create a list, and I use this all the time, like this:
> (car '(1 2 3))
1
But it doesn’t always work like I’d expect. For example, I tried to create a list of functions, like this, but it didn’t work:
> (define math-fns '(+ - * /))
> (map (lambda (fn) (fn 1)) math-fns)
application: not a procedure;
expected a procedure that can be applied to arguments
given: '+
When I use list, it works:
> (define math-fns (list + - * /))
> (map (lambda (fn) (fn 1)) math-fns)
'(1 -1 1 1)
Why? I thought ' was just a convenient shorthand, so why is the behavior different?
TL;DR: They are different; use list when in doubt.
A rule of thumb: use list whenever you want the arguments to be evaluated; quote “distributes” over its arguments, so '(+ 1 2) is like (list '+ '1 '2). You’ll end up with a symbol in your list, not a function.
An in-depth look at list and quote
In Scheme and Racket, quote and list are entirely different things, but since both of them can be used to produce lists, confusion is common and understandable. There is an incredibly important difference between them: list is a plain old function, while quote (even without the special ' syntax) is a special form. That is, list can be implemented in plain Scheme, but quote cannot be.
The list function
The list function is actually by far the simpler of the two, so let’s start there. It is a function that takes any number of arguments, and it collects the arguments into a list.
> (list 1 2 3)
(1 2 3)
This above example can be confusing because the result is printed as a quoteable s-expression, and it’s true, in this case, the two syntaxes are equivalent. But if we get slightly more complicated, you’ll see that it is different:
> (list 1 (+ 1 1) (+ 1 1 1))
(1 2 3)
> '(1 (+ 1 1) (+ 1 1 1))
(1 (+ 1 1) (+ 1 1 1))
What’s going on in the quote example? Well, we’ll discuss that in a moment, but first, take a look at list. It’s just an ordinary function, so it follows standard Scheme evaluation semantics: it evaluates each of its arguments before they get passed to the function. This means that expressions like (+ 1 1) will be reduced to 2 before they get collected into the list.
This behavior is also visible when supplying variables to the list function:
> (define x 42)
> (list x)
(42)
> '(x)
(x)
With list, the x gets evaluated before getting passed to list. With quote, things are more complicated.
Finally, because list is just a function, it can be used just like any other function, including in higher-order ways. For example, it can be passed to the map function, and it will work appropriately:
> (map list '(1 2 3) '(4 5 6))
((1 4) (2 5) (3 6))
The quote form
Quotation, unlike list, is a special part of Lisps. The quote form is special in part because it gets a special reader abbreviation, ', but it’s also special even without that. Unlike list, quote is not a function, and therefore it does not need to behave like one—it has rules of its own.
A brief discussion of Lisp source code
In Lisp, of which Scheme and Racket are derivatives, all code is actually made up of ordinary data structures. For example, consider the following expression:
(+ 1 2)
That expression is actually a list, and it has three elements:
the + symbol
the number 1
the number 2
All of these values are normal values that can be created by the programmer. It’s really easy to create the 1 value because it evaluates to itself: you just type 1. But symbols and lists are harder: by default, a symbol in the source code does a variable lookup! That is, symbols are not self-evaluating:
> 1
1
> a
a: undefined
cannot reference undefined identifier
As it turns out, though, symbols are basically just strings, and in fact we can convert between them:
> (string->symbol "a")
a
Lists do even more than symbols, because by default, a list in the source code calls a function! Doing (+ 1 2) looks at the first element in the list, the + symbol, looks up the function associated with it, and invokes it with the rest of the elements in the list.
Sometimes, though, you might want to disable this “special” behavior. You might want to just get the list or get the symbol without it being evaluated. To do this, you can use quote.
The meaning of quotation
With all this in mind, it’s pretty obvious what quote does: it just “turns off” the special evaluation behavior for the expression that it wraps. For example, consider quoteing a symbol:
> (quote a)
a
Similarly, consider quoteing a list:
> (quote (a b c))
(a b c)
No matter what you give quote, it will always, always spit it back out at you. No more, no less. That means if you give it a list, none of the subexpressions will be evaluated—do not expect them to be! If you need evaluation of any kind, use list.
Now, one might ask: what happens if you quote something other than a symbol or a list? Well, the answer is... nothing! You just get it back.
> (quote 1)
1
> (quote "abcd")
"abcd"
This makes sense, since quote still just spits out exactly what you give it. This is why “literals” like numbers and strings are sometimes called “self-quoting” in Lisp parlance.
One more thing: what happens if you quote an expression containing quote? That is, what if you “double quote”?
> (quote (quote 3))
'3
What happened there? Well, remember that ' is actually just a direct abbreviation for quote, so nothing special happened at all! In fact, if your Scheme has a way to disable the abbreviations when printing, it will look like this:
> (quote (quote 3))
(quote 3)
Don’t be fooled by quote being special: just like (quote (+ 1)), the result here is just a plain old list. In fact, we can get the first element out of the list: can you guess what it will be?
> (car (quote (quote 3)))
quote
If you guessed 3, you are wrong. Remember, quote disables all evaluation, and an expression containing a quote symbol is still just a plain list. Play with this in the REPL until you are comfortable with it.
> (quote (quote (quote 3)))
''3
(quote (1 2 (quote 3)))
(1 2 '3)
Quotation is incredibly simple, but it can come off as very complex because of how it tends to defy our understanding of the traditional evaluation model. In fact, it is confusing because of how simple it is: there are no special cases, there are no rules. It just returns exactly what you give it, precisely as stated (hence the name “quotation”).
Appendix A: Quasiquotation
So if quotation completely disables evaluation, what is it good for? Well, aside from making lists of strings, symbols, or numbers that are all known ahead of time, not much. Fortunately, the concept of quasiquotation provides a way to break out of the quotation and go back into ordinary evaluation.
The basics are super simple: instead of using quote, use quasiquote. Normally, this works exactly like quote in every way:
> (quasiquote 3)
3
> (quasiquote x)
x
> (quasiquote ((a b) (c d)))
((a b) (c d))
What makes quasiquote special is that is recognizes a special symbol, unquote. Wherever unquote appears in the list, then it is replaced by the arbitrary expression it contains:
> (quasiquote (1 2 (+ 1 2)))
(1 2 (+ 1 2))
> (quasiquote (1 2 (unquote (+ 1 2))))
(1 2 3)
This lets you use quasiquote to construct templates of sorts that have “holes” to be filled in with unquote. This means it’s possible to actually include the values of variables inside of quoted lists:
> (define x 42)
> (quasiquote (x is: (unquote x)))
(x is: 42)
Of course, using quasiquote and unquote is rather verbose, so they have abbreviations of their own, just like '. Specifically, quasiquote is ` (backtick) and unquote is , (comma). With those abbreviations, the above example is much more palatable.
> `(x is: ,x)
(x is: 42)
One final point: quasiquote actually can be implemented in Racket using a rather hairy macro, and it is. It expands to usages of list, cons, and of course, quote.
Appendix B: Implementing list and quote in Scheme
Implementing list is super simple because of how “rest argument” syntax works. This is all you need:
(define (list . args)
args)
That’s it!
In contrast, quote is a lot harder—in fact, it’s impossible! It would seem totally feasible, since the idea of disabling evaluation sounds a lot like macros. Yet a naïve attempt reveals the trouble:
(define fake-quote
(syntax-rules ()
((_ arg) arg)))
We just take arg and spit it back out... but this doesn’t work. Why not? Well, the result of our macro will be evaluated, so all is for naught. We might be able to expand to something sort of like quote by expanding to (list ...) and recursively quoting the elements, like this:
(define impostor-quote
(syntax-rules ()
((_ (a . b)) (cons (impostor-quote a) (impostor-quote b)))
((_ (e ...)) (list (impostor-quote e) ...))
((_ x) x)))
Unfortunately, though, without procedural macros, we can’t handle symbols without quote. We could get closer using syntax-case, but even then, we would only be emulating quote’s behavior, not replicating it.
Appendix C: Racket printing conventions
When trying the examples in this answer in Racket, you may find that they do not print as one would expect. Often, they may print with a leading ', such as in this example:
> (list 1 2 3)
'(1 2 3)
This is because Racket, by default, prints results as expressions when possible. That is, you should be able to type the result into the REPL and get the same value back. I personally find this behavior nice, but it can be confusing when trying to understand quotation, so if you want to turn it off, call (print-as-expression #f), or change the printing style to “write” in the DrRacket language menu.
The behavior you are seeing is a consequence of Scheme not treating symbols as functions.
The expression '(+ - * /) produces a value which is a list of symbols. That's simply because (+ - * /) is a list of symbols, and we are just quoting it to suppress evaluation in order to get that object literally as a value.
The expression (list + - * /) produces a list of functions. This is because it is a function call. The symbolic expressions list, +, -, * and / are evaluated. They are all variables which denote functions, and so are reduced to those functions. The list function is then called, and returns a list of those remaining four functions.
In ANSI Common Lisp, calling symbols as functions works:
[1]> (mapcar (lambda (f) (funcall f 1)) '(+ - * /))
(1 -1 1 1)
When a symbol is used where a function is expected, the top-level function binding of the symbol is substituted, if it has one, and everything is cool. In effect, symbols are function-callable objects in Common Lisp.
If you want to use list to produce a list of symbols, just like '(+ - * /), you have to quote them individually to suppress their evaluation:
(list '+ '- '* '/)
Back in the Scheme world, you will see that if you map over this, it will fail in the same way as the original quoted list. The reason is the same: trying to use a symbol objects as a functions.
The error message you are being shown is misleading:
expected a procedure that can be applied to arguments
given: '+
This '+ being shown here is (quote +). But that's not what the application was given; it was given just +, the issue being that the symbol object + isn't usable as a function in that dialect.
What's going on here is that the diagnostic message is printing the + symbol in "print as expression" mode, a feature of Racket, which is what I guess you're using.
In "print as expression" mode, objects are printed using a syntax which must be read and evaluated to produce a similar object. See the StackOverflow question "Why does the Racket interpreter write lists with an apostroph before?"

Of what use is identity function in Racket?

What is the use of identity function? It simply returns the same value. Hence, instead of putting (identity x), why not simply put x? Could someone give some examples of using identity function in Racket/Scheme? There are no examples on these documentation page: https://docs.racket-lang.org/htdp-langs/beginner.html#%28def.htdp-beginner.%28%28lib._lang%2Fhtdp-beginner..rkt%29.identity%29%29 and https://docs.racket-lang.org/reference/procedures.html?q=identity#%28def.%28%28lib._racket%2Ffunction..rkt%29._identity%29%29
The identity function is mostly useful as an argument to certain higher-order functions (functions which take functions as arguments) when a function performs a certain sort of mapping customized by its argument, and you wish to pass the value through unchanged.†
One extremely common idiom in Scheme/Racket is using (filter identity ...) to remove all #f values from a list:
> (filter identity '(1 2 #f 4))
'(1 2 4)
This works because filter applies the provided function to each of the elements of a list, then discards values that result in #f. By using identity, the values themselves are checked. In this sense, identity is the functional “no-op”.
You may sometimes see this idiom spelled (filter values ...) instead of (filter identity ...) because values happens to be the identity function when provided with one argument, and it comes from racket/base instead of racket/function. I prefer the version that uses identity explicitly, though, because I think it is a little bit clearer what’s going on.
† This description of the identity function comes from this nice answer for the Haskell equivalent question.

Why is "1 2 3" a valid Scheme expression?

This is valid Scheme
1 2 3
and returns 3. But this is not valid
(1 2 3)
and neither is this valid
(1) (2) (3)
It makes sense that the last two are not valid. But I don't see how the first one should be valid? Can someone please explain?
Probably, the REPL of your implementation is reading a non-empty sequence of expressions and evaluating all of them and giving the sequence of results. (I believe that this behavior of the REPL is implementation specific. R7RS does not mention it in its §5.7. It might vary with other implementations of Scheme and I never used it; I agree with coredump's answer that it may be a fancy and useful feature)
Scheme is able to return and handle several values, e.g. with call-with-values & values ; see also this
So technically 1 2 3 is not a single expression, but a sequence of three expressions. A call to (read) won't give you such a sequence. And on guile 2 on Linux (+ 2 (read)) 55 66 gives immediately two results 57 66, not three (after waiting for input).
Read also about call/cc, continuations, and CPS. There might be some indirect relation (how does your REPL deal internally with them when (read)ing expressions....)
The REPL is reading multiple forms in sequence (this is also how Common Lisp implementations work). Given that the user entered multiple forms, what else could happen?
displaying an error would be correct, but unhelpful
discarding previous/next forms would be confusing
IMHO the behavior of reading all the given forms as-if they were in an implicit progn is the most useful for the user. It is also consistent with how files are read, and allow you for example to paste the content of a file directly into the REPL.
The first one is valid because it is considered a simple expression. Scheme doesn't do anything with it and just echoes it back to you. This is true not only for numbers, but also for all constants including strings, symbols and even lists (if you quote them to create an actual list rather than a function call). For ex. if you type in '(1 2 3), it will be just echoed back to you without being interpreted.
The way scheme, and generally other lisps, evaluate expression can be described by two broad rules (and this is probably a naive interpretation):
If the entered expression is a constant (a string, number, symbol, list or something else), the constant itself is the value. Just echo it back.
If the expression is of the form (procedure arg1 ... arg-n), find the value of procedure, evaluate or find the values of all the arguments (arg1 to arg-n), and apply procedure to the arguments.
More details are available at Evaluating Scheme Expressions chapter in the the book The Scheme Programming Language 4e.
The key observation is that it is not allowed to put in extra parenthesis in Scheme. In (+ 1 2) the expression + is evaluated and the result is a plus-function. That function is applied to 1 2 and you get the result 3.
In your example (1) means evaluate 1 and the result is 1. Then apply 1 to no arguments. And since 1 is not a function you will get an error.
In the example (1 2 3) your system attempts to apply 1 to the arguments 2 and 3 and get an error.
In short: Parenthesis in arithmetics is used to group an operation - in Scheme it means function application.
Finally: 1 2 3 is not a single expression but three expressions. The last of which evaluates to 3.

What is the semantic difference between defining a name with and without parentheses?

(Though this is indeed simple question, I find sometimes it is common mistakes that I made when writing Scheme program as a beginner.)
I encountered some confusion about the define special form. A situation is like below:
(define num1
2)
(define (num2)
2)
I find it occurs quite often that I call num2 without the parentheses and program fails. I usually end up spending hours to find the cause.
By reading the r5rs, I realized that definition without parenthesis, e.g. num1, is a variable; while definition with parenthesis, e.g. num2, is a function without formal parameters.
However, I am still blurred about the difference between a "variable" and "function".
From a emacs lisp background, I can only relate above difference to similar idea as in emacs lisp:
In Emacs Lisp, a symbol can have a value attached to it just as it can
have a function definition attached to it.
[here]
Question: Is this a correct way of understanding the difference between enclosed and non-enclosed definitions in scheme?
There is no difference between a value and a function in Scheme. A function is just a value that can be used in a particular way - it can be called (as opposed to other kinds of value, such as numbers, which cannot be called, but can be e.g. added, which a function cannot).
The parentheses are just a syntactic shortcut - they're a faster, more readable (to experts) way of writing out the definition of the name as a variable containing a function:
(define (num)
2)
;is exactly the same as
(define num
(lambda () 2) )
The second of these should make it more visually obvious that the value being assigned to num is not a number.
If you wanted the function to take arguments, they would either go within the parentheses (after num, e.g. (num x y) in the first form, or within lambda's parentheses (e.g. (lambda (x y)... in the second.
Most tutorials for the total beginner actually don't introduce the first form for several exercises, in order to drive home the point that it isn't separate and doesn't really provide any true functionality on its own. It's just a shorthand to reduce the amount of repetition in your program's text.
In Scheme, all functions are values; variables hold any one value.
In Scheme, unlike Common Lisp and Emacs Lisp, there are no different namespaces for functions and other values. So the statement you quoted is not true for Scheme. In Scheme a symbol is associated with at most one value and that value may or may not be a function.
As to the difference between a non-function value and a nullary function returning that value: In your example the only difference is that, as you know, num2 must be applied to get the numeric value and num1 does not have to be and in fact can't be applied.
In general the difference between (define foo bar) and (define (foo) bar) is that the former evaluated bar right now and foo then refers to the value that bar has been evaluated to, whereas in the latter case bar is evaluated each time that (foo) is used. So if the expression foo is costly to calculate, that cost is paid when (and each time) you call the function, not at the definition. And, perhaps more importantly, if the expression has side effects (like, for example, printing something) those effects happen each time the function is called. Side effects are the primary reason you'd define a function without parameters.
Even though #sepp2k has answered the question, I will make it more clearer with example:
1 ]=> (define foo1 (display 23))
23
;Value: foo1
1 ]=> foo1
;Unspecified return value
Notice in the first one, foo1 is evaluated on the spot (hence it prints) and evaluated value is assigned to name foo1. It doesn't evaluate again and again
1 ]=> (define (foo2) (display 23))
;Value: foo2
1 ]=> foo2
;Value 11: #[compound-procedure 11 foo2]
1 ]=> (foo2)
23
;Unspecified return value
Just foo2 will return another procedure (which is (display 23)). Doing (foo2) actually evaluates it. And each time on being called, it re-evaluates again
1 ]=> (foo1)
;The object #!unspecific is not applicable.
foo1 is a name that refers a value. So Applying foo1 doesn't make sense as in this case that value is not a procedure.
So I hope things are clearer. In short, in your former case it is a name that refers to value returned by evaluating expression. In latter case, each time it is evaluated.

How to access an element in a list?

I have this list:
("x" "y" "z")
How do I extract an element from the list? (In this case I'm interested in the first element in the list, but I'm looking for a general solution.)
You really should read an intro to elisp or something before you try to use it. The Elisp manual which comes with Emacs in some distributions is quite good.
(nth 0 mylist)
https://www.gnu.org/software/emacs/manual/html_node/elisp/List-Elements.html
If you know the list position of the element, then use (nth 0 mylist), as #triplee indicated.
If you want to test element equality (in this case, string equality) then use this:
(car (member "y" mylist))
(member "y" mylist) returns the sublist (tail) ("y" "z"), and car returns the first element of that sublist (car is the same as nth with 0 first arg).
If the string you want is not a member of the list, then member returns the empty list nil (aka ()), and car of that list returns nil. So member is both (a) a predicate for testing list membership (returns nil' for not present and non-nil` for present) and (b) a way to extract the first sublist (tail) that contains the element you seek.
Read subsections List Elements and Using Lists as Sets of section Lists of GNU Emacs Lisp Reference Manual. The manual is your friend, it's the first place you should look, when you have a question about Elisp. To access the manual inside Emacs, view it using Info system by pressing F1imelispEnter, or navigate around Info-mode manually.
If you write serious Elisp code, I recommend installing dash package, which has plenty of functions to query and transform lists. For example, if you want to find a first (or last) element that satisfies a predicate, use -first or -last:
(-first 'evenp '(1 2 3 4 5 6)) ; 2
(-last 'evenp '(1 2 3 4 5 6)) ; 6

Resources