I am a scheme beginner and
I am wondering how to explain this piece of scheme code? Looks so preculiar!
(define (calc2 exp)
(match exp
[(? number? x) x]))
I know match gives a pattern, but how to explain this weird pattern?
(? number? x)
Thanks!
The pattern (? expr pat ...) is part of the syntax of the match macro. It applies expr to the patterns and checks whether the result is a true value. In this case, that means it will check if (number? x) returns true, where x is exp. If it does, the function will return whatever you passed to it as exp. If not, it will raise a match exception.
In other words, calc2 simply raises an exception for any value passed to it that is not a number, and returns it's argument otherwise. For more information on how pattern matching works in Racket, check out http://docs.racket-lang.org/reference/match.html
(? number? x) in this when the pattern matching detects a ? as first item in the pattern then it and's all the predicates after the ?. So in this case it means that your exp should be a number and then as x is not a predicate it just mean set x same as exp.
From the documentation:
(? expr pat ...) — applies expr to the value to be matched, and checks
whether the result is a true value; the additional pats must also
match; i.e., ? combines a predicate application and an and pattern.
However, ?, unlike and, guarantees that expr is matched before any of
the pats.
Example:
> (match '(1 3 5)
[(list (? odd?) ...) 'yes])
'yes
Related
as a lisp newbie i'm stuck with a general problem: I want to query data, generate a sum over it and want to calculate further with this results.
For example i sum up 33 77 and want to divide the result:
(defun sum (L)
(reduce '+ L))
(/ 999 (sum '(33 77)))
Without the divison i receive the correct sum. When i'm trying to proceed further, i get an error that a numerical function was given an argument.
A type-of query (type-of '(sum '(33 77))) says it's CONS
What's the correct handling for results for further calculation?
(type-of '(sum '(33 77)))
The evaluation of the above consists first in evaluating '(sum '(33 77)), and call function type-of with the result of the evaluation.
'(sum '(33 77)) is the same as (quote (sum (quote (33 77)))), except that the apostrophe is a reader syntax ' that turns what follows, say x, into (quote x).
The quote form is self-evaluating, meaning the value it evaluates to is the exact value that was quoted, here (sum '(33 77)).
That value is data representing code: it literally is a list, built at read-time, that contains the symbol sum followed by another element, a list whose first element is quote that is followed by another list containing 33 and 77, literal numbers.
Since the value of your expression is a list, and since lists are built by chaining cons-cells, it is normal that type-of returns cons.
If you remove one level of quotes:
(type-of (sum '(33 77)))
Then the evaluation of (sum '(33 77)) follows the normal evaluation of function calls, by first evaluating the argument, '(33 77), a literal list, and calling sum with it. Your function returns the sum, 110, and this is the value that is given when calling type-of. In that case, you should obtain a numerical type.
I've written a prlog recursive factorial clause which is:
factorial(X,Y):-
(X>1)
-> factorial(X-1,X*Y)
; write(Y).
The problem is, for any valid call[for example, factorial(5,1). ], it is giving an expression rather than a value[(5-1-1-1)* ((5-1-1)* ((5-1)* (5*1)))]. How can I get a value rather than an expression.
The comment by #lurker is a bit simplistic. Comparison operators do evaluate expressions. So, your code could be made to work:
factorial(X,Y):- X>1 -> factorial(X-1,F), Y=X*F ; Y=1.
?- factorial(5,X),F is X.
X = 5*((5-1)*((5-1-1)*((5-1-1-1)*1))),
F = 120.
I am trying to implement tail call recursive factorial in Common Lisp, to try it and just experience it.
I copied some code and rewrote it in Common Lisp like so:
(defun tailrecsum (x &key (running-total 0 running-total-p))
(if (= x 0)
(if running-total-p running-total 0)
(tailrecsum (- x 1) (+ running-total x))))
However, I get first a warning:
SIMPLE-WARNING:
The function has an odd number of arguments in the keyword portion.
And when trying to run it, I get an error:
SIMPLE-PROGRAM-ERROR:
odd number of &KEY arguments
Why can't I have an odd number of keyword arguments? What's the problem with that and what can I do about it?
For example in Python I could write:
def func(a, b=10):
print([a, b])
So I would have an odd number, one, of keyword arguments. No issues there.
The error doesn't refer to the number of keyword parameters; rather it means the number of arguments you call the function with. Since keywords arguments by definition need to be in pairs (:KEYWORD VALUE), having odd number of arguments means you must be missing something.
In this case you're missing the keyword in
(tailrecsum (- x 1) (+ running-total x))
which should be
(tailrecsum (- x 1) :running-total (+ running-total x))
Suppose we have a symbol, with a symbol value and a function value and a property list and let us call it q. Suppose also that we have a function f with formal parameter v, e.g. (f (v) ... ) and call the function like (f q).
My question is: what is exactly passed to v? Are
the value of q;
the function value of q;
property list of q,
passed to the formal parameter v?
If they are all passed to v, then I am puzzled by the fact that we really need the functions funcall and apply. If v would really have both the value and the function value, then it can surely itself decide that when we write (v 3), then it must use the function value of v instead of (funcall v 3). And when we use (setq v 3) then it must use the value of v.
What is exactly passed to v and why v is not a symbol, but just a "parameter" or "variable", is an enigma to me. But I believe that it was in Lisp 1.5 really a symbol. But in common Lisp, there seems to be some
room to confusion.
If you have
(f q)
it means call the function f with the value of q.
Lisp sees that f is a function, so the whole (f q) is a function form.
Lisp evaluates q to its value.
Lisp calls f with one value.
Lisp binds the local variable v to the passed value
Lisp executes the body of the function f
...
v is in the source code a symbol, but it denotes a variable. In compiled code the symbol is gone. Since Common Lisp uses lexical bindings, variables are now lexical references.
Since you're quoting it, you're passing the symbol qnot any of its values; those values can be accessed within f by using (symbol-value v) or (symbol-function v).
The reason you need funcall is because Common Lisp uses the function value of a symbol when it appears at the head of a list to evaluate. So if you write
(v 3)
it will call the function value of the symbol v. But the value that was passed to f is in the value of v, not the function value. But when you write
(funcall v 3)
v is in the argument list, so it's evaluated to get its value. That value is the symbol q, and when you try to call a symbol, funcall looks up its function value, so it's equivalent in this case to
(funcall (symbol-function v) 3)
The value of variable q is passed.
(f q) is an evaluated form, in this case the name q is interpreted as a variable.
If you want to acces the function value or property list of the name q in function f, you need to quote the name and say 'q. By doing this, you're referring to the global registry of function values and property list values, instead of the local information passed inside function f.
Only the value of variable q is passed inside function f.
I must be missing something very basic here.
I need to extract a capture group from a match in common lisp.
When I eval in the interpreter (an sbcl implementation):
`(cl-ppcre::scan-to-strings ".*?(\\d).png" "sample1.png")`
I get:
"sample1.png"
#("1")
But if I bind that expression to a value, say
`(setq number (cl-ppcre::scan-to-strings ".*(\\d).png" "sample1.png"))`
The value of number is becomes "sample1.png". How do I get the "1", which is printed?
Your question
You are looking for
(setf (values match position)
(cl-ppcre::scan-to-strings ".*(\\d).png" "sample1.png"))
See also multiple-value-bind et al.
Under the hood
Common lisp functions can return multiple values.
This corresponds to "tuple" return value in other languages, such as Python.
So, when a lisp function, such as floor, return multiple values, a Python user will write something like
(f,r) = floor(10,3)
and floor will (usually) allocate a tuple, which is captured when you write fr = floor(10,3).
CL multiple values do not allocate extra storage, but the extra values are discarded unless you specifically ask for them:
(setf (values f r) (floor 10 3))
will capture both values, but (setf f (floor 10 3)) will discard r.