Operating on multiple lists? - elisp

On page 224 of Common Lisp: A Gentle Introduction to Symbolic Computation this example is given with the output.
> (mapcar #'(lambda (x y) (list x 'gets y))
'(fred wilma george diane)
'(job1 job2 job3 job4))
((FRED GETS JOB1)
(WILMA GETS JOB2)
(GEORGE GETS JOB3)
(DIANE GETS JOB4))
Is there a way to do the same thing in Emacs Lisp? The other example is also interesting because only 3 results, the number of elements in the shortest list, are produced.
> (mapcar #'+ '(1 2 3) '(10 20 30 40 50))
(11 22 33)

Emacs has mapcar* in the cl package which does exactly that. Here is the documentation:
Apply FUNCTION to each element of SEQ, and make a list of the results.
If there are several SEQs, FUNCTION is called with that many arguments,
and mapping stops as soon as the shortest list runs out. With just one
SEQ, this is like mapcar. With several, it is like the Common Lisp
mapcar function extended to arbitrary sequence types.

Related

Is it legal to modify a list created using quasiquote?

From my understanding, it is not legal to modify a list created using quote:
(let ((numbers '(3 2 1)))
(set-car! numbers 99) ; Illegal.
numbers)
What about lists created using quasiquote? Is it legal to modify lists created using quasiquote?
(let ((numbers `(3 2 1)))
(set-car! numbers 99) ; Legal?
numbers)
(let ((numbers `(,(+ 1 2) 2 1)))
(set-car! numbers 99) ; Legal?
numbers)
The short answer is no, this isn't "legal", and certainly this should never be done in a program that aims to be portable. R6RS and R7RS have almost identical language around this, so I'll just quote from R6RS, Section 11.17 Quasiquotation:
A quasiquote expression may return either fresh, mutable objects or literal structure for any structure that is constructed at run time during the evaluation of the expression. Portions that do not need to be rebuilt are always literal.
Section 4.2.8 of R7RS has the same language, except that it says "newly allocated" instead of "fresh".
Since it is an error to attempt to modify literals in Scheme, it is an error to modify the result of a quasiquote form. This is something that you may seem get away with sometimes, but it will bite you sooner or later. The real catch here is that "portions that do not need to be rebuilt are always literal". Other portions may or may not be literal.
More specifically for OP posted code, `(3 2 1) is guaranteed to evaluate to a list literal by the semantics of quasiquote described in Section 11.17 of R6RS:
Semantics: If no unquote or unquote-splicing forms appear within the <qq template>, the result of evaluating (quasiquote <qq template>) is equivalent to the result of evaluating (quote <qq template>).
R7RS contains similar language in Section 4.2.8. Since (quote (3 2 1)) creates a list literal, the expression `(3 2 1) must also evaluate to a list literal.
On the other hand, OP code `(,(+ 1 2) 2 1) must evaluate (+ 1 2) and insert that result into the resulting structure. In this case, unquote is used via the , operator, so the resulting list structure may or may not be a list literal.
To take one more example, consider the quasiquoted expression `(,(+ 1 2) (2 1)). Here the main result is a list structure which may or may not be a list literal, but the element (2 1) of the resulting structure is guaranteed to be a list literal since it does not need to be rebuilt in the construction of the final result.

Function Arguments and Continuations

My question is about function arguments in conjunction with continuations.
Specifically, what behavior is required, and what is allowed.
Suppose you have a function call (f arg1 arg2 arg3). I realize that
a compliant Scheme implementation is allowed to evaluate the arguments
arg1, arg2, and arg3 in any order. That's fine. But now suppose
that, say, arg2 creates a continuation. In general, some of the other
arguments may be evaluated before arg2 is evaluated, and some may be
evaluated after arg2 is evaluated.
Suppose that, in the Scheme implementation we're using, arg1 is
evaluated before arg2. Further, suppose that f modifies its local
copy of the first argument. Later, when the continuation created
during the evaluation of arg2 is called, arg3 will be evaluated
again and f will be called.
The question is this: When f is called a second time, via the
continuation, what value must/may its first argument have? Does it
need to be the same value that arg1 evaluated to? Or may it be the
modified value from the previous call to f? (Again, this example
assumes that arg1 is evaluated before arg2, but the same issue
applies with different argument evaluation orders. I.e., if arg3 is
evaluated before arg2, then the question applies to arg3.)
I have tried this in a couple of Scheme implementations, and have obtained
differing results. I took into account different orders of evaluation of
the arguments (it's easy to track it by having the argument expressions
log when they're being evaluated). Ignoring that difference, one
implementation always used the original argument values, and another
sometimes used the original argument values, and sometimes used the
modified argument values, depending on whether f was an inline
lambda vs. a global function. Presumably the difference is due to
whether the actual arguments end up being copied into the function's
local variables, or whether they are used in-place.
Here is a version that uses a global function:
(define (bar x cc y)
(set! x (* x 2))
(set! y (* y 3))
(format #t "~a ~a\n" x y)
cc)
(define (foo a b)
(let* ((first #t)
(cb (bar
(+ a 10)
(call/cc (lambda (x) x))
(+ b 100))))
(if first
(begin
(set! first #f)
cb)
(cb '()))))
(define cc (foo 1 2))
(call/cc cc)
(call/cc cc)
The above version uses the original argument values when calling
the function bar in both of the Scheme implementations that I tested.
The function bar sees 11 for the first argument and 102 for the
third argument each time it is called. The output is:
22 306
22 306
22 306
Now, here is a version that replaces the global function with an inline
lambda:
(define (foo a b)
(let* ((first #t)
(cb ((lambda (x cc y)
(set! x (* x 2))
(set! y (* y 3))
(format #t "~a ~a\n" x y)
cc)
(+ a 10)
(call/cc (lambda (x) x))
(+ b 100))))
(if first
(begin
(set! first #f)
cb)
(cb '()))))
(define cc (foo 1 2))
(call/cc cc)
(call/cc cc)
In one of the Scheme implementations I tested (BiwaScheme), this
behaves the same as the previous version. I.e., the called function
always sees the original argument values.
In another Scheme implementation (Gosh/Gauche), this behaves
differently from the previous version. In this case, the called
function uses the modified value of the first argument. In other
words, it handles the inline lambda differently, taking advantage of
the fact that it can see the function definition, and is presumably
using a more direct argument passing mechanism that avoids having to
copy them. Since it isn't copying the arguments, the ones that were
evaluated before the continuation point retain their modified values.
The lambda sees 11 and 102 for the first and third arguments the
first time, then it sees 22 and 102 the second time, and 44 and
102 the third time. So the continuation is picking up the modified
argument values. The output is:
22 306
44 306
88 306
So again, my question is this: Are both behaviors allowed by the
Scheme standard (R6RS and/or R7RS)? Or does Scheme in fact require
that the original argument values be used when the continuation is
invoked?
Update: I originally reported that the Gauche Scheme implementation
gave the three different sets of values shown above. That was true,
but only for certain versions of Gauche. The version I originally
tested was Gauche 0.9.3.3, which shows the three different sets of
values. I later found a site that has three different versions of
Gauche. The oldest, Gauche 0.9.4, also shows the three different
sets of values. But the two newer versions, Gauche 0.9.5 and Gauche
0.9.8, both show the repeated values:
22 306
22 306
22 306
This argues pretty strongly that this was considered a bug which
has since been fixed (just as everyone has been saying).
A continuation will literally create a copy of the stack in the moment of calling call/cc, copy that is also called a control-point. The continuation also stores inside it a copy of the current dynamic environment (more precisely, of the state-space from the dynamic-wind module) and a copy of the thread-local state.
So, when you reactivate the continuation, everything will continue from the moment when it was saved. If some arguments were previously evaluated, their evaluation is saved on the stack and the rest of arguments will be re-evaluated a second time. (as a remark, the dynamic state in scheme is implemented over the dynamic-wind module, so saving the dynamic state involved saving the state of dynamic wind, which is a combination between stack and the state-space (a tree keeping the in-out thunks for dynamic-wind calls)).
The stack starts from the top-level (actually there are other stacklets that represent continuations of the shutdown procedures, but those are touched only when you finish your code), they are not memorized when you call call/cc. So, if in a file/repl you gave 2 expressions, such as
(+ (f 1) 2)
(display "ok")
each of these expressions will have its own stacklet, so saving the continuation within f won't re-evaluate the display.
I think this should be enough to analyse your problem. The arguments are evaluated in unspecified order.
EDIT:
Concerning the answer of foo, for sure it is not correct 22 306 44 306 88 306 but it's correct 22 306 22 306 22 306.
I never used any of these 2 implementations. It is a bug in the implementation that does not bind x after each invocation of the (lambda (x cc y) ...), as the capture of the continuation is made outside the lambda().
The implementation bug seems obvious, it's in their generation of Scode -- they keep x on the stack, despite the fact that set! x was present, which should be an indicator to allocate x as a box on the heap.
While the evaluation order is undefined in the report it is not undefined in an implementtions CPS code. Eg.
(f (+ x 4) (call/cc cont-fun)), where x is a free variable, becomes either:
(call/cc&
cont-fun&
(lambda (v2)
(+& x
4
(lambda (v1)
(f& v1 v2 halt&))))
Or:
(+& x
4
(lambda (v1)
(call/cc&
cont-fun&
(lambda (v2)
(f& v1 v2 halt&)))))
So if the continuation function cont-fun& mutates x this will have an impact of the result in the version that evaluates the arguments right to left since the addition is done in the continuation of it, but in the second version mutating x will not affect the addition since the value is already computed in the passed value v2 and in the event the continuation is captured and rerun this value will never be recomputed. In the first version though you always compute v1 so here mutating the free variable x will affect the result.
If you as a developer wants to avoid this you let* the damn thing:
(let* ((a2 (call/cc cont-fun))
(a1 (+ x 4)))
(f a1 a2))
This code will force the behavior of the addition always being in the continuation of determining a2.
Now I avoided using your mutating examples, but in reality those are just bindings being rerouted. You have overcomplicated bar as the set! does not have any lasting effect. It is always the same as:
(define (bar x cc y)
(format #t "~a ~a\n" (* x 2) (* y 3))
cc)
The continuation caught in:
(bar (+ a 10)
(call/cc (lambda (x) x))
(+ b 100))
Regardless of the order we know the call to bar is the final continuation after evaluating all 3 expressions and then do the body of the let* the first and the 2 consecutive times.
Your second version doesn't change anything since the function doesn't rely on free variables. How the consecutive call to the continuation gave you 44 and 88 is most definitely a compiler optimization that fails. It shouldn't do that. I would have reported it as a bug.

Whole fraction numbers in Scheme

Is there an easy way to display whole rational numbers for example:
(average '(1 2 3 4)) ;returns 2 1/2
I would like it to return 5/2. Thank you.
This is DrRacket-specific behavior. It customizes the Racket print handler to print out certain values in "pretty" ways, some of which aren't even plain text. For example, DrRacket will print images as pictures in the REPL, and it will print syntax objects as fully interactive widgets that display source information along with the datum structure.
Racket reserves the print function to be customized, and it doesn't guarantee the output of such a function. If you want consistent output, use write, which will always produce plain text unless explicitly altered by the programmer.
(write (/ 5 2)) ; => 5/2
Note that in the REPL, print will use the same textual representation that write uses for exact, rational numbers.
You can use numerator and denominator to get the pieces you want. Something like:
(let* ((avg (average '(1 2 3 4)))
(num (numerator avg))
(den (denominator avg)))
(printf "~a/~a~n" num den)))

Why do they quote empty lists in Scheme?

I'm going through this Scheme tutorial and in section 3 (Making Lists) the guy says you should write '() to represent an empty list. But for every test I've wrote seems that it has the very same effect as using just ().
Also, as far as I understand, the quote means the interpreter won't evaluate the expression, but seems that the interpreter knows what's after the ' symbol, because doing this (cons 1 '()) yields (1), while doing this (cons 1 'abc) yields (1 . abc), so it knows '() is an empty list but 'abc is not.
Some Scheme implementations permit bare () as a synonym for '(), but only the quoted form is standard.
As for your second question: consider
(define abc '(1 2 3))
(define def '(1 2 3))
(cons 0 'abc)
(cons 0 'def)
(cons 0 abc)
(cons 0 def)
In the first two expressions, abc and def are not evaluated, so they stay symbols. In the latter two, they are evaluated to the objects they stand for, which are both equal to the list (1 2 3).
TL;DR: To make sure your applications work as as designed you should quote the empty list since it's unsure if it will work otherwise. see the long answer below.
As for how Scheme works for quoted values, quoting '(+ 3 4 5) makes an expression a constant that is not to be evaluated. It much like making a string with code in it, like "if( a == 0 ) return 4;" in Java or C. The difference is that a quoted expression are structured data rather than byte sequences.
(cons 1 'abc) and (cons 1 '()) does the same. A cons has two placeholders for values and those two expressions sets two values in the exact same manner. It's only display (and the repl) that knows that a list that ends with () should display differently and not (1 . ()) like it actually is stored.
The long answer about the need to quote the empty list
It all boils down to the standard you're using. Most implementations today are R5RS and it requires the empty list be quoted since the empty list is not an expression. Implementations might still allow it though since it won't interfere with a proper Scheme application. Heres a quote from the R5RS report:
Note: In many dialects of Lisp, the empty combination, (), is a
legitimate expression. In Scheme, combinations must have at least one
subexpression, so () is not a syntactically valid expression.
This actually happened in R3RS (under Procedure calls) so it's been around for a while. When looking for it in R6RS however it seems to have disappeared from the section making me think they have reverted it so that it would be self evaluating. However, I cannot find it in the language changes part.
When looking at the R7RS draft (NB: PDF), the part from R5RS is back so I guess this was an error in the R6RS report. This might be the reason racket (and probably other implementors) allow () as an expression in R6RS to be sure it will work even when the report is ambiguous about it.

Self-referential data structures in Lisp/Scheme

Is there a way to construct a self-referential data structure (say a graph with cycles) in lisp or scheme? I'd never thought about it before, but playing around I can find no straightforward way to make one due to the lack of a way to make destructive modification. Is this just an essential flaw of functional languages, and if so, what about lazy functional languages like haskell?
In Common Lisp you can modify list contents, array contents, slots of CLOS instances, etc.
Common Lisp also allows to read and write circular data structures. Use
? (setf *print-circle* t)
T
; a list of two symbols: (foo bar)
? (defvar *ex1* (list 'foo 'bar))
*EX1*
; now let the first list element point to the list,
; Common Lisp prints the circular list
? (setf (first *ex1*) *ex1*)
#1=(#1# BAR)
; one can also read such a list
? '#1=(#1# BAR)
#1=(#1# BAR)
; What is the first element? The list itself
? (first '#1=(#1# BAR))
#1=(#1# BAR)
?
So-called pure Functional Programming Languages don't allow side-effects. Most Lisp dialects are not pure. They allow side-effects and they allow to modify data-structures.
See Lisp introduction books for more on that.
In Scheme, you can do it easily with set!, set-car!, and set-cdr! (and anything else ending in a bang ('!'), which indicates modification):
(let ((x '(1 2 3)))
(set-car! x x)
; x is now the list (x 2 3), with the first element referring to itself
)
Common Lisp supports modification of data structures with setf.
You can build a circular data structure in Haskell by tying the knot.
You don't need `destructive modification' to construct self-referential data structures; e.g., in Common Lisp, '#1=(#1#) is a cons-cell that contains itself.
Scheme and Lisp are capable of making destructive modifications: you can construct the circular cons above alternatively like this:
(let ((x (cons nil nil)))
(rplaca x x) x)
Can you let us know what material you're using while learning Lisp/Scheme? I'm compiling a target list for our black helicopters; this spreading of misinformation about Lisp and Scheme has to be stopped.
Yes, and they can be useful. One of my college professors created a Scheme type he called Medusa Numbers. They were arbitrary precision floating point numbers that could include repeating decimals. He had a function:
(create-medusa numerator denominator) ; or some such
which created the Medusa Number that represented the rational. As a result:
(define one-third (create-medusa 1 3))
one-third => ; scheme hangs - when you look at a medusa number you turn to stone
(add-medusa one-third (add-medusa one-third one-third)) => 1
as said before, this is done with judicious application of set-car! and set-cdr!
Not only is it possible, it's pretty central to the Common Lisp Object System: standard-class is an instance of itself!
I upvoted the obvious Scheme techniques; this answer addresses only Haskell.
In Haskell you can do this purely functionally using let, which is considered good style. One nice example is regexp-to-NFA conversion. You can also do it imperatively using IORefs, which is considered poor style as it forces all your code into the IO monad.
In general Haskell's lazy evaluation lends itself to lovely functional implementations of both cyclic and infinite data structures. In any complex let binding, all things bound may be used in all definitions. For example translating a particular finite-state machine into Haskell is a snap, no matter how many cycles it may have.
CLOS example:
(defclass node ()
((child :accessor node-child :initarg :child)))
(defun make-node-cycle ()
(let* ((node1 (make-instance 'node))
(node2 (make-instance 'node :child node1)))
(setf (node-child node1) node2)))
Tying the Knot (circular data structures in Haskell) on StackOverflow
See also the Haskell Wiki page: Tying the Knot
Hmm, self referential data structures in Lisp/Scheme, and SICP streams are not mentioned? Well, to summarize, streams == lazily evaluated list. It might be exactly the kind of self reference you've intended, but it's a kind of self reference.
So, cons-stream in SICP is a syntax that delays evaluating its arguments. (cons-stream a b) will return immediately without evaluating a or b, and only evaluates a or b when you invoke car-stream or cdr-stream
From SICP, http://mitpress.mit.edu/sicp/full-text/sicp/book/node71.html:
>
(define fibs
(cons-stream 0
(cons-stream 1
(add-streams (stream-cdr fibs)
fibs))))
This definition says that fibs is a
stream beginning with 0 and 1, such
that the rest of the stream can be
generated by adding fibs to itself
shifted by one place:
In this case, 'fibs' is assigned an object whose value is defined lazily in terms of 'fibs'
Almost forgot to mention, lazy streams live on in the commonly available libraries SRFI-40 or SRFI-41. One of these two should be available in most popular Schemes, I think
I stumbled upon this question while searching for "CIRCULAR LISTS LISP SCHEME".
This is how I can make one (in STk Scheme):
First, make a list
(define a '(1 2 3))
At this point, STk thinks a is a list.
(list? a)
> #t
Next, go to the last element (the 3 in this case) and replace the cdr which currently contains nil with a pointer to itself.
(set-cdr! (cdr ( cdr a)) a)
Now, STk thinks a is not a list.
(list? a)
> #f
(How does it work this out?)
Now if you print a you will find an infinitely long list of (1 2 3 1 2 3 1 2 ... and you will need to kill the program. In Stk you can control-z or control-\ to quit.
But what are circular-lists good for?
I can think of obscure examples to do with modulo arithmetic such as a circular list of the days of the week (M T W T F S S M T W ...), or a circular list of integers represented by 3 bits (0 1 2 3 4 5 6 7 0 1 2 3 4 5 ..).
Are there any real-world examples?

Resources