Implementation of scheme vector-set - vector

I am trying to understand how vector-set! is implemented. It looks to me like vector-set! is a special form - much like set! is. When I look at examples using vector-set! I see the following, desirable behavior (in guile).
(define test (lambda (v i) (vector-set! v i 0)))
(define v (make-vector 5 1))
v
$1 = #(1 1 1 1 1)
(test v 0)
v
$2 = #(0 1 1 1 1)
I can also do this (in guile)
(define test (lambda (v i) (vector-set! (eval v (interaction-environment)) i 0)))
(test (quote v) 3)
v
$21 = #(0 1 1 0 1)
Contrasting to the set! behavior:
(define a 1)
(define test2 (lambda b (begin (set! b 0) b)))
(test2 (quote a))
$26 = 0
a
$27 = 1
In this case, to my understanding the set! changes b to 0 (and not the 'evaluated" b (which should be a). The eval trick from above does not work here.
My question is: How is vector-set! implemented compared to set! (or set-variable-value!). Does vector-set! peak at it's first argument? Or something else? I have tried to look at some of scheme implementations but extracting the gist from the code is tricky. Perhaps someone has an explanation or a link to some (sicp style) scheme implementation.

The function vector-set! is a so-called primitive.
It is a function (not a special form), but it must be implemented within the runtime.
Note: A special form is a form that uses an evaluation order different from the order used in a normal application. Therefore if, cond, or and others are special forms.
Some implementations (I can't remember if Guile is one of them) has a function primitive? that can be used to test whether a function is a primitive or not.
> (primitive? vector-set!)
#t

In "some SICP-style Scheme implementation", where vector-set! would be handled by eval-vector-mutation, it could be
(define (eval-vector-mutation exp env)
; exp = (vector-set! vec idx val)
(let ((vec (eval (vector-mutation-vec exp) env))
(idx (eval (vector-mutation-idx exp) env))
(val (eval (vector-mutation-val exp) env)))
(begin
(set-car! (cddr (drop vec idx)) val) ; srfi-1 drop
vec)))
and make-vector handled by
(define (eval-vector-creation exp env)
; exp = (make-vector cnt val)
(let ((cnt (eval (vector-creation-cnt exp) env))
(val (eval (vector-creation-val exp) env)))
(cons 'vector ; tagged list
(cons cnt ; vector size
(make-list cnt val))))) ; srfi-1 make-list
Here vectors are represented by tagged lists in the underlying Scheme implementation (not the Scheme being defined), and its mutation primitives, like set-car!, are used to manipulate them. If your implementation language were C, say, you'd just use C arrays as your vectors representation, or perhaps a structure coupling an array with the additional pertinent info, like its size ,etc.

Related

Recursively find element position in list using LISP

Here is my problem:Without using MEMBER, complete the following definition of a recursive function POS
such that if L is a list and E is an element of L then (POS E L) returns the position of the first
occurrence of E in L, and such that if E is not an element of L then (POS E L) returns 0.This is the solution have come up with:
(DEFUN POS (E L)
(COND ((ENDP L) 0)
((EQUAL E (CAR L)) 1 )
(T
(+ 1 (POS E (CDR L)) )
)))
The algorithm works fine if the element I am looking for is in the list. My problem is that when the element is not in the list I will get the length of the list.
Example:
list[1,2,3,4] Find: 5 will reurn 4
How do I get it to return 0 if element is not found. And as it is functional programming I can't use loops or variable.
You always return (+ 1 <recursive-call>). But what if the recursive result is zero? You should check that return value before computing the result.
if you find an occurence, return 1
if you don't find a result, compute recursively, which gives you R
if R is zero, return zero
otherwise, return R + 1
As an aside, the Common Lisp way would be:
(or (position E L :test #'equal) 0)
As #coredump has explained, the problem is that you are always adding 1 to the result, even if you haven't found the element. I would keep the track of the current position within the list by adding an extra parameter to function POS:
(defun pos (element list &optional (start 0))
(cond ((endp list) 0)
((equal element (first list)) (1+ start))
(t (pos element (rest list) (1+ start)))))
Testing:
(pos 'a '(b a c d a))
2
(pos 'a '(a d a f g))
1
(pos 'w '(a b c d e f))
0
One extra benefit: this function generates iterative process due to recursive call being in tail-call position (however, ANSI Common Lisp does not guarantee it will do tail-call optimization! AFAIK, CLisp doesn't do it; SBCL and CCL will do for optimized code, see DECLARE). More idiomatic Common Lisp solution would be using LOOP:
(defun pos (element list)
(loop for x in list
counting x into pos
when (equal element x)
return pos
end
finally (return 0)))

Are there any standard functions to iterate across predicates by applying to single value?

There are always many functions for iterating across list of values like mapcar, every, some.
I need iteration across predicates for single value:
(let ( (val (complex-expr ...)) )
(or (pred1 val) (pred2 val) ... (predN val)))
(let ( (val (complex-expr ...)) )
(and (pred1 val) (pred2 val) ... (predN val)))
Are there any standard functions doing above code with syntax:
(some-p val pred1 pred2 ... predN)
(every-p val pred1 pred2 ... predN)
UPDATE FYI Elisp have this function in it's standard library:
run-hook-with-args-until-success
run-hook-with-args-until-failure
run-hook-with-args
The standard doesn't include anything exactly like what you're asking for, but it does include some and every for computing (or (f x1) (f x2) … (f xn)) and (and (f x1) (f x2) … (f xn)):
CL-USER> (some 'evenp '(1 2 3 4 5))
T
CL-USER> (every 'evenp '(1 2 3 4 5))
NIL
What you're trying to do fits into this paradigm, except that the f you need should take each xi, treat it as a function, and call it with some value. Some and every still work here:
CL-USER> (let ((value 3))
(some (lambda (predicate) (funcall predicate value)) '(evenp symbolp oddp)))
T
CL-USER> (let ((value "hello"))
(some (lambda (predicate) (funcall predicate value)) '(characterp numberp)))
NIL
Of course, you can wrap that up another in function to avoid writing the lambda function every time:
(defun some-p (value predicates)
(some (lambda (predicate)
(funcall predicate value))
predicates))
CL-USER> (some-p "hello" '(characterp numberp))
NIL
CL-USER> (some-p 3 '(characterp numberp))
T
If you really want the function to variadic (like you showed in your question), you can do it with a &rest parameter, but do note that it's not the style most of these kinds of functions use:
(defun some-p (value &rest predicates)
(some (lambda (predicate)
(funcall predicate value))
predicates))
CL-USER> (some-p 3 'characterp 'numberp)
T
CL-USER> (some-p "hello" 'characterp 'numberp)
NIL
It's much more common to take the arguments as a list, though. Two good reasons for this (which are part of the same phenomenon) are that: (i) it's easier to pass the list from another source. E.g., it's easier to do [a] than [b]:
(let ((preds '(p1 p2 ... pn)))
(some-p-list value preds) ; [a]
(apply 'some-p-rest value preds)) ; [b]
Even if you don't mind the apply in [b], as Rainer Joswig noted in comments, there's a constant call-arguments-limit in a Common Lisp implementation that puts a limit on the number of arguments a function can be called with. It's often big, but it can be as small as 50. That means that if preds has 50 elements, then (apply 'some-p-rest value preds) would fail.
There is no standard function, but it is easy to write:
Note that you can also use the LOOP macro for that:
some
CL-USER 10 > (loop with value = 4
for pred in (list #'numberp #'plusp #'oddp)
thereis (funcall pred value))
T
every
CL-USER 11 > (loop with value = 3
for pred in (list #'numberp #'plusp #'oddp)
always (funcall pred value))
T
every-p
CL-USER 16 > (defun every-p (value predicates)
(loop for predicate in predicates
always (funcall predicate value)))
EVERY-P
CL-USER 17 > (every-p 3 (list #'numberp #'plusp #'oddp))
T

Possible to do this without using eval in Common Lisp?

In my little project I have two arrays, lets call them A and B. Their values are
#(1 2 3) and #(5 6 7). I also have two lists of symbols of identical length, lets call them C and D. They look like this: (num1 num2 num3) and (num2 num3 num4).
You could say that the symbols in lists C and D are textual labels for the values in the arrays A and B. So num1 in A is 1. num2 in A is 2. num2 in B is 5. There is no num1 in B, but there is a num3, which is 6.
My goal is to produce a function taking two arguments like so:
(defun row-join-function-factory (C D)
...body...)
I want it to return a function of two arguments:
(lambda (A B) ...body...)
such that this resulting function called with arguments A and B results in a kind of "join" that returns the new array: #(1 5 6 7)
The process taking place in this later function obtained values from the two arrays A and B such that it produces a new array whose members may be represented by (union C D). Note: I haven't actually run (union C D), as I don't actually care about the order of the symbols contained therein, but lets assume it returns (num1 num2 num3 num4). The important thing is that (num1 num2 num3 num4) corresponds as textual labels to the new array #(1 5 6 7). If num2, or any symbol, exists in both C and D, and subsequently represents values from A and B, then the value from B corresponding to that symbol is kept in the resulting array rather than the value from A.
I hope that gets the gist of the mechanical action here. Theoretically, I want row-join-function-factory to be able to do this with arrays and symbol-lists of any length/contents, but writing such a function is not beyond me, and not the question.
The thing is, I wish the returned function to be insanely efficient, which means that I'm not willing to have the function chase pointers down lists, or look up hash tables at run time. In this example, the function I require to be returned would be almost literally:
(lambda (A B)
(make-array 4
:initial-contents (list (aref A 0) (aref B 0) (aref B 1) (aref B 2))))
I do not want the array indexes calculated at run-time, or which array they are referencing. I want a compiled function that does this and this only, as fast as possible, which does as little work as possible. I do not care about the run-time work required to make such a function, only the run-time work required in applying it.
I have settled upon the use of (eval ) in row-join-function-factory to work on symbols representing the lisp code above to produce this function. I was wondering, however, if there is not some simpler method to pull off this trick that I am not thinking of, given one's general cautiousness about the use of eval...
By my reasoning, i cannot use macros by themselves, as they cannot know what all values and dimensions A, B, C, D could take at compile time, and while I can code up a function that returns a lambda which mechanically does what I want, I believe my versions will always be doing some kind of extra run-time work/close over variables/etc...compared to the hypothetical lambda function above
Thoughts, answers, recommendations and the like are welcome. Am I correct in my conclusion that this is one of those rare legitimate eval uses? Apologies ahead of time for my inability to express the problem as eloquently in english...
(or alternatively, if someone can explain where my reasoning is off, or how to dynamically produce the most efficient functions...)
From what I understand, you need to precompute the vector size and the aref args.
(defun row-join-function-factory (C D)
(flet ((add-indices (l n)
(loop for el in l and i from 0 collect (list el n i))))
(let* ((C-indices (add-indices C 0))
(D-indices (add-indices D 1))
(all-indices (append D-indices
(set-difference C-indices
D-indices
:key #'first)))
(ns (mapcar #'second all-indices))
(is (mapcar #'third all-indices))
(size (length all-indices)))
#'(lambda (A B)
(map-into (make-array size)
#'(lambda (n i)
(aref (if (zerop n) A B) i))
ns is)))))
Note that I used a number to know if either A or B should be used instead of capturing C and D, to allow them to be garbage collected.
EDIT: I advise you to profile against a generated function, and observe if the overhead of the runtime closure is higher than e.g. 5%, against a special-purpose function:
(defun row-join-function-factory (C D)
(flet ((add-indices (l n)
(loop for el in l and i from 0 collect (list el n i))))
(let* ((C-indices (add-indices C 0))
(D-indices (add-indices D 1))
(all-indices (append D-indices
(set-difference C-indices
D-indices
:key #'first)))
(ns (mapcar #'second all-indices))
(is (mapcar #'third all-indices))
(size (length all-indices))
(j 0))
(compile
nil
`(lambda (A B)
(let ((result (make-array ,size)))
,#(mapcar #'(lambda (n i)
`(setf (aref result ,(1- (incf j)))
(aref ,(if (zerop n) 'A 'B) ,i)))
ns is)
result))))))
And validate if the compilation overhead indeed pays off in your implementation.
I argue that if the runtime difference between the closure and the compiled lambda is really small, keep the closure, for:
A cleaner coding style
Depending on the implementation, it might be easier to debug
Depending on the implementation, the generated closures will share the function code (e.g. closure template function)
It won't require a runtime license that includes the compiler in some commercial implementations
I think the right approach is to have a macro which would compute the indexes at compile time:
(defmacro my-array-generator (syms-a syms-b)
(let ((table '((a 0) (b 0) (b 1) (b 2)))) ; compute this from syms-a and syms-b
`(lambda (a b)
(make-array ,(length table) :initial-contents
(list ,#(mapcar (lambda (ai) (cons 'aref ai)) table))))))
And it will produce what you want:
(macroexpand '(my-array-generator ...))
==>
#'(LAMBDA (A B)
(MAKE-ARRAY 4 :INITIAL-CONTENTS
(LIST (AREF A 0) (AREF B 0) (AREF B 1) (AREF B 2))))
So, all that is left is to write a function which will produce
((a 0) (b 0) (b 1) (b 2))
given
syms-a = (num1 num2 num3)
and
syms-b = (num2 num3 num4)
Depends on when you know the data. If all the data is known at compile time, you can use a macro (per sds's answer).
If the data is known at run-time, you should be looking at loading it into an 2D array from your existing arrays. This - using a properly optimizing compiler - should imply that a lookup is several muls, an add, and a dereference.
By the way, can you describe your project in a wee bit more detail? It sounds interesting. :-)
Given C and D you could create a closure like
(lambda (A B)
(do ((result (make-array n))
(i 0 (1+ i)))
((>= i n) result)
(setf (aref result i)
(aref (if (aref use-A i) A B)
(aref use-index i)))))
where n, use-A and use-index are precomputed values captured in the closure like
n --> 4
use-A --> #(T nil nil nil)
use-index --> #(0 0 1 2)
Checking with SBCL (speed 3) (safety 0) the execution time was basically identical to the make-array + initial-contents version, at least for this simple case.
Of course creating a closure with those precomputed data tables doesn't even require a macro.
Have you actually timed how much are you going to save (if anything) using an unrolled compiled version?
EDIT
Making an experiment with SBCL the closure generated by
(defun merger (clist1 clist2)
(let ((use1 (list))
(index (list))
(i1 0)
(i2 0))
(dolist (s1 clist1)
(if (find s1 clist2)
(progn
(push NIL use1)
(push (position s1 clist2) index))
(progn
(push T use1)
(push i1 index)))
(incf i1))
(dolist (s2 clist2)
(unless (find s2 clist1)
(push NIL use1)
(push i2 index))
(incf i2))
(let* ((n (length index))
(u1 (make-array n :initial-contents (nreverse use1)))
(ix (make-array n :initial-contents (nreverse index))))
(declare (type simple-vector ix)
(type simple-vector u1)
(type fixnum n))
(print (list u1 ix n))
(lambda (a b)
(declare (type simple-vector a)
(type simple-vector b))
(let ((result (make-array n)))
(dotimes (i n)
(setf (aref result i)
(aref (if (aref u1 i) a b)
(aref ix i))))
result)))))
runs about 13% slower than an hand-written version providing the same type declarations (2.878s instead of 2.529s for 100,000,000 calls for the (a b c d)(b d e f) case, a 6-elements output).
The inner loop for the data based closure version compiles to
; 470: L2: 4D8B540801 MOV R10, [R8+RCX+1] ; (aref u1 i)
; 475: 4C8BF7 MOV R14, RDI ; b
; 478: 4C8BEE MOV R13, RSI ; source to use (a for now)
; 47B: 4981FA17001020 CMP R10, 537919511 ; (null R10)?
; 482: 4D0F44EE CMOVEQ R13, R14 ; if true use b instead
; 486: 4D8B540901 MOV R10, [R9+RCX+1] ; (aref ix i)
; 48B: 4B8B441501 MOV RAX, [R13+R10+1] ; load (aref ?? i)
; 490: 4889440B01 MOV [RBX+RCX+1], RAX ; store (aref result i)
; 495: 4883C108 ADD RCX, 8 ; (incf i)
; 499: L3: 4839D1 CMP RCX, RDX ; done?
; 49C: 7CD2 JL L2 ; no, loop back
The conditional is not compiled to a jump but to a conditional assignment (CMOVEQ).
I see a little room for improvement (e.g. using CMOVEQ R13, RDI directly, saving an instruction and freeing a register) but I don't think this would shave off that 13%.

Lisp macro (or function) for nested loops

Is it possible to write a Common Lisp macro that takes a list of dimensions and variables, a body (of iteration), and creates the code consisting of as many nested loops as specified by the list?
That is, something like:
(nested-loops '(2 5 3) '(i j k) whatever_loop_body)
should be expanded to
(loop for i from 0 below 2 do
(loop for j from 0 below 5 do
(loop for k from 0 below 3 do
whatever_loop_body)))
Follow up
As huaiyuan correctly pointed out, I have to know the parameters to pass to macro at compile time. If you actually need a function as I do, look below.
If you are ok with a macro, go for the recursive solution of 6502, is wonderful.
You don't need the quotes, since the dimensions and variables need to be known at compile time anyway.
(defmacro nested-loops (dimensions variables &body body)
(loop for range in (reverse dimensions)
for index in (reverse variables)
for x = body then (list y)
for y = `(loop for ,index from 0 to ,range do ,#x)
finally (return y)))
Edit:
If the dimensions cannot be decided at compile time, we'll need a function
(defun nested-map (fn dimensions)
(labels ((gn (args dimensions)
(if dimensions
(loop for i from 0 to (car dimensions) do
(gn (cons i args) (cdr dimensions)))
(apply fn (reverse args)))))
(gn nil dimensions)))
and to wrap the body in lambda when calling.
CL-USER> (nested-map (lambda (&rest indexes) (print indexes)) '(2 3 4))
(0 0 0)
(0 0 1)
(0 0 2)
(0 0 3)
(0 0 4)
(0 1 0)
(0 1 1)
(0 1 2)
(0 1 3)
(0 1 4)
(0 2 0)
(0 2 1)
...
Edit(2012-04-16):
The above version of nested-map was written to more closely reflect the original problem statement. As mmj said in the comments, it's probably more natural to make index range from 0 to n-1, and moving the reversing out of the inner loop should improve efficiency if we don't insist on row-major order of iterations. Also, it's probably more sensible to have the input function accept a tuple instead of individual indices, to be rank independent. Here is a new version with the stated changes:
(defun nested-map (fn dimensions)
(labels ((gn (args dimensions)
(if dimensions
(loop for i below (car dimensions) do
(gn (cons i args) (cdr dimensions)))
(funcall fn args))))
(gn nil (reverse dimensions))))
Then,
CL-USER> (nested-map #'print '(2 3 4))
Sometimes an approach that is useful is writing a recursive macro, i.e. a macro that generates code containing another invocation of the same macro unless the case is simple enough to be solved directly:
(defmacro nested-loops (max-values vars &rest body)
(if vars
`(loop for ,(first vars) from 0 to ,(first max-values) do
(nested-loops ,(rest max-values) ,(rest vars) ,#body))
`(progn ,#body)))
(nested-loops (2 3 4) (i j k)
(print (list i j k)))
In the above if the variable list is empty then the macro expands directly to the body forms, otherwise the generated code is a (loop...) on the first variable containing another (nested-loops ...) invocation in the do part.
The macro is not recursive in the normal sense used for functions (it's not calling itself directly) but the macroexpansion logic will call the same macro for the inner parts until the code generation has been completed.
Note that the max value forms used in the inner loops will be re-evaluated at each iteration of the outer loop. It doesn't make any difference if the forms are indeed numbers like in your test case, but it's different if they're for example function calls.
Hm. Here's an example of such a macro in common lisp. Note, though, that I am not sure, that this is actually a good idea. But we are all adults here, aren't we?
(defmacro nested-loop (control &body body)
(let ((variables ())
(lower-bounds ())
(upper-bounds ()))
(loop
:for ctl :in (reverse control)
:do (destructuring-bind (variable bound1 &optional (bound2 nil got-bound2)) ctl
(push variable variables)
(push (if got-bound2 bound1 0) lower-bounds)
(push (if got-bound2 bound2 bound1) upper-bounds)))
(labels ((recurr (vars lowers uppers)
(if (null vars)
`(progn ,#body)
`(loop
:for ,(car vars) :upfrom ,(car lowers) :to ,(car uppers)
:do ,(recurr (cdr vars) (cdr lowers) (cdr uppers))))))
(recurr variables lower-bounds upper-bounds))))
The syntax is slightly different from your proposal.
(nested-loop ((i 0 10) (j 15) (k 15 20))
(format t "~D ~D ~D~%" i j k))
expands into
(loop :for i :upfrom 0 :to 10
:do (loop :for j :upfrom 0 :to 15
:do (loop :for k :upfrom 15 :to 20
:do (progn (format t "~d ~d ~d~%" i j k)))))
The first argument to the macro is a list of list of the form
(variable upper-bound)
(with a lower bound of 0 implied) or
(variable lower-bound upper-bounds)
With a little more love applied, one could even have something like
(nested-loop ((i :upfrom 10 :below 20) (j :downfrom 100 :to 1)) ...)
but then, why bother, if loop has all these features already?

For-loop in scheme

I want to define a for-n function in scheme that takes 3 parameters, start and stop are integers and fn is a function. I want the for-n function to call fn with start then start+1 ... and in the end with stop.
Also I want to store all the values fn returns in a list. Please help me get started. I am an experienced programmer but have just starting learning scheme.
This is the function definition I got:
[edit]
(define (fn a)
a
)
(define (for-n start stop fn)
(cond
((> start stop) (quote ()))
((= start stop) (list(fn start)))
(else (list(for-n (+ start 1) stop fn)))
)
)
> (for-n 3 5 fn)
(list (list (list 5)))
When (for-n 3 5 fn) is called, I want it to return
(3 4 5), what am I doing wrong?
[edit-2]
Thanks for the help everyone. I got function working now. Here is what I got:
(define (for-n start stop fn)
(cond
((> start stop) (quote ()))
((= start stop) (list(fn start)))
(else (cons (fn start) (for-n (+ start 1) stop fn)))
)
)
You seldom want to use list to recursively construct lists. Lists are built with cons and null (aka '()); list is just a convenience function to create a fixed sized list.
(list 1 2 3) = (cons 1 (cons 2 (cons 3 null)))
You should only have two cases in your cond clause: either you're done or you aren't.
Examples help. In particular, pick examples that are related by your recursive calls. You included the example (for-n 3 5 fn). What about (for-n 4 5 fn); what should it return? Now, given start = 3, stop = 5, and (for-n 4 5 fn) = whatever you think it should produce, how can you construct the answer you think (for-n 3 5 fn) should produce?
I highly recommend How to Design Programs (text available online) as an introduction to functional programming.
Here's a solution that uses SRFI 1:
(define (for-n start stop fn)
(map fn (iota (- stop start) start)))
If this is for homework, then it's up to you to define iota, and perhaps map also. :-D
Another solution using a different strategy (also uses SRFI 1):
(define (for-n start stop fn)
(unfold-right (lambda (x) (< x start))
fn sub1 (sub1 stop)))
where sub1 == (lambda (x) (- x 1)). Of course, you have to implement unfold-right yourself, in this case.
Hopefully from the above two example solutions, you have enough ideas to build your own from-scratch solution. :-)
I'm new to scheme too, but here's what I came up with for a generic for loop that seems to work for me:
(define (for i end-cond end-fn fn var)
(if (end-cond i)
var
(for (end-fn i) end-cond end-fn fn (fn var))
)
)
So the canonical:
for (i=0; i > 5; i++) {
print i;
}
return i;
Can be written as:
(define i 0) (for i (lambda (x) (> 5 x)) (lambda (y) (+ 1 y)) display i)
...and you can see why the paradigm doesn't translate well, though you can replace those lambdas with named functions to make it more readable.
--
Self-edit 2015:
This is awful, and the wrong way to do functional programming. A 'map' or 'fold' based approach is much better.

Resources