Elisp: cannot grasp effect of setq and sort - elisp

When evaluating the following code in Emacs, I get (2 3) as the final value of x. I'd expect (1 2 3). What am I missing?
(setq x '(2 1 3))
(sort x '<)
x

If you read sort's documentation, you will find that it returns the sorted list, and the input list is modified by side effects. It does not say that the argument list will contain the sorted result -- It is just somehow modified by the sorting algorithm. Or, to put it shortly: sort is destructive.
So, you'll want to bind/assign sort's return value:
elisp> (setq x '(2 1 3))
(2 1 3)
elisp> (setq x (sort x '<))
(1 2 3)
elisp> x
(1 2 3)

I don't have much experience with elisp, but it is behaving correctly due to the implementation with car and cdr. Check http://www.gnu.org/software/emacs/elisp/html_node/Rearrangement.html#Rearrangement

Related

Any way to map functions with more than one argument in Scheme/Racket?

I'm currently doing an introductory course in Racket/Scheme, and am currently studying map, apply, and fold. For the most part, I've been assuming that map can only work on lambdas that accept a single argument. However, for certain problems I would find it incredibly useful to get around this somewhat - say, having a function that can be mapped to a list whilst also carrying an accumulator that updates independently for each recursive function call. While I can't get much more specific than that for fear of violating Honor Code, is there any way to get around being unable to give each recursive call an accumulator if you plan to use map?
map takes as many lists as you want:
(map + '(1 2 3) '(3 2 1) '(3 3 3)) ; ==> (7 7 7)
fold has an accumulator:
(foldl (lambda (a b c acc) (+ a b c acc)) 1 '(1 2 3) '(3 2 1) '(3 3 3)) ; ==> 22

DrRacket 2 list inputs and reversing only one

I'll preface this by saying this is for an assignment, but I am not sure how to approach this after going through other stackoverflow questions for an hour or two.
I'm attempting to create a reverse function that accepts 2 lists as input and returns the first list reverse appended with the second list.
Example: (reverse '(1 2) '(3 4)) --> (2 1 3 4)
My code is below, I have tried conditional statements such as when the first list is NOT null then do the main logic, then when it is only return l2 (which still returned (3 4 2 1) instead of (2 1 3 4).
The problem I'm having is that no matter what I do the second list is always at the beginning of the first reversed list.
(define (myreverse l1 l2)
(if (null? l) l2)
(append (myreverse(cdr l1) l2) (list(car l1))))
Consider the following:
(reverse '(1 2 3 4))
=> '(4 3 2 1)
(append (reverse '(1 2)) '(3 4))
=> '(2 1 3 4)
Think about how you can implement reverse, and how you can use it in your myreverse procedure.
With racket/scheme it is very helpful to think of these kinds of problems from the bottom up.
For example, what do you do when the first list is null?? Well, you're done! so just return the second list. What do you do when it has just one element? Well, we tack that element onto the second list and we're done. But a moment's thought tells us that all the cases are now covered.
(define (rev-first left right)
(if (null? left)
right
(rev-first (??? left) (???? right))))
Actually this kind of recursion is captured with foldl and foldr more generally. But I don't know if it's instructive for you at this point.

Scheme expression evaluation

I am going through the book - The Scheme Programming Language, 4th Edition. In an exercise, there is an expression ((car (list + - * /)) 2 3). Below are the steps in which I believe the expression will be evaluated. Please let me know if my understanding is correct.
The expression (list + - * /) is evaluated to a list of procedures: (+ - * /). (I understand that list always produces a "proper list", could someone please state a few differences between using list and cons?)
The expression (car (+ - * /)) is evaluated to the symbol + which evaluates to a procedure. (I don't really understand how (car (+ - * /)) is evaluated, typing (car (+ - * /)) at the REPL prompt produces an error).
The expression (+ 2 3) is evaluated to 5.
I would like if I could get some other / in depth explanation.
Yes! However the procedures doesn't have literal representation so when you evaluate + you get some crazy textual representation like #<primitive-procedure-+> and copying it and pasting it into the repl won't give you the same object back. The same with lists. When you evaluate (list 1 2 3) you get (1 2 3) but you cannot just write (1 2 3) since it will think it should call 1 as a procedure with two arguments. (list 1 2 3) makes (cons 1 (cons 2 (cons 3 '()))) a chain of nested pairs. That the last cdr is () is what makes it proper. Thus the primitive that allows list to do it's thing is cons.
Wrong. You have an evaluated expression (list + - * /) to something like (#<primitive-procedure-+> #<...> #<...> #<...>). A list of evaluated variables and you now see their visual representations. Doing car on it gives you the first object #<primitive-procedure-+> which is the same you get when you evaluate the global variable +. There are no symbols involved in this step. The previous step didn't involve symbols either since bare symbols are variables. 'test becomes a symbol while test becomes whatever the variable pointed to. All procedures by name are just variables getting evaluated before application. It's the default behaviour in Scheme.
Since the object is the same as the value + is it will add the rest of the operands together after they have been evaluated. Since they all are numbers the arguments passed to apply stay the same, but if you have expressions there like (+ (* 3 3) (* 4 4)) then the operands like (* 3 3) need to get evaluated and it's result is what is applied.
You can apply substitution rules. It's not what the Scheme interpreter does, but any variable can be replaced by the value it has and every expression can be replaced by its result as long as you do not mutate anything:
((car (list + - * /)) (- 5 2) (/ 4 2)) ; == (car (list + - * /)) evaluates to the same value as the variable +
(+ (- 5 2) (/ 4 2)) ; == (- 5 2) evaluates to 3, (/4 2) evaluates to 2
(+ 3 2) ; == (+ 3 2) evaluates to 5
; ==> 5 (the result)
Notice I substitute (car (list + - * /)) with the variable + and not a symbol. They both are the same: (eq? (car (list + - * /)) +) ; ==> #t
The stepper in DrRacket is the perfect tool for exploring evaluation order.
The stepper allows you to see the effect of one evaluation step at a time.
You can even step backwards.
The stepper however only works in the Beginner and Intermediate languages.
The image is from the following program using the Intermediate language.
(car (list + - * /))
(+ 2 3)

Why does '(1 2 3) evaluate to a list en Lisp (Scheme)?

The quote (') is used to introduce a pre-evaluated value, so (quote x) results in the symbol x and not what the symbol evalutes to.
Numbers, Booleans, characters and strings are self-evaluating in Scheme, so quoting them doesn't matter.
But why does (quote (1 2 3)) or (quote ()) answers #t to the predicate list?.
Should't the result be a "pre-evaluated" value? But in this case (1 2 3) has actually been evaluated to (list 1 2 3)?
Thank you.
pre-evaluated value
I'm not sure where you got that term from. I've never used it. It's not "pre-evaluated", it's unevaluated.
This is really all works from the fact Lisp (and Scheme) is Homoiconic: the structure of the program really uses lists and atoms underneath.
quote is the dual to eval: (eval (list '+ '1 '2 '3)) (and since a quoted number is just the number, (eval (list '+ 1 2 3)) does it as well) is the opposite of (quote '(+ 1 2 3)).
An evaluated list is a call, so an unevaluated call is a list.
Should't the result be a "pre-evaluated" value? But in this case (1 2 3) has actually been evaluated to (list? 1 2 3)?
You're missing some parentheses here! You get (list? '(1 2 3)) (or (list? (quote (1 2 3)). That is, (list? (list 1 2 3)). Which is true.
You can check the opposite with (eval (list '+ 1 2 3)): you get 6.
Note: Some values just evaluate to themselves (like numbers or functions. You can throw eval at it as many times as you want, and it won't change a thing: (eval (eval (eval 1))) is just 1.)
(quote (+ 1 2 3)) = '(+ 1 2 3) = (list '+ '1 '2 '3) = (list '+ 1 2 3) (numbers are self-evaluating, i.e. evaluating to self).
(eval '(+ 1 2 3)) = (+ 1 2 3) = 6. And (eval '(1 2 3)) = (1 2 3) = error.
The first identity is just syntactical. The central identity here is the second one, '(+ 1 2 3) = (list '+ '1 '2 '3). It holds because everything is evaluated in Lisp, but before that, it must be read. Which means, converted from textual source code to actual data structures.
Since ( ... ) parentheses denote lists, reading ( ... ) forms creates lists. Then, evaluating the quoted form just returns that form as is (i.e. non-evaluated). The token + gets read as a symbol +; the literals 1, 2, 3 get read as numbers 1, 2, 3. So the end result is the same as the result of evaluating the form (list '+ '1 '2 '3).
And of course all this still applies without the + inside, as well.
The quote introduces an unevaluated value, not pre-evaluated, whatever that means.
When the expression (quote X) is treated as a form to be evaluated, it simply evaluates to X itself. X is not treated as a form to be evaluated to a value, but rather the resulting value is the syntax X itself.
Quote is a way of the program expressing, "I want to use a piece of my own syntax as a value". And that's precisely what a "literal" is in computer science: a piece of program text reflected back into the program as a run-time value.
In Lisp, atoms other than symbols denote themselves when evaluated. The syntax 3 evaluates to the integer 3. They are the same thing: Lisp syntax is a data structure, and in that data structure, an integer literal 3 is already represented by the object that it denotes.
Thus, under evaluation, there is no difference between (quote 3) and just 3. "Give me the syntax 3 itself" and "give me the value of the syntax 3" are the same: just 3.
Under (quote (1 2 3)), the syntax being quoted is (1 2 3). That syntax is the list object that it looks like; quote just regurgitates it. If were to evaluate the (1 2 3) form, it would be an error: it looks like 1 is being used as an operator or function, with arguments 2 and 3. When quote is itself evaluated, it suppresses this evaluation and just yields the (1 2 3) as-is.
Because the (1 2 3) is a piece of the program syntax, however, there is a restriction in the language that this list may not be modified. An operation like (inc (car (quote (1 2 3)))) which tries to change the list to (2 2 3) invokes undefined behavior. Essentially, the program is trying to modify its own syntax; if for a moment we disregard the additional complexity that Lisp is a compiled language, this is de facto self-modifying code.

Map, Filter, Foldr in DrRacket/Scheme

Programming language: Scheme/DrRacket
We're currently going over map, filter, and foldr in my comp sci class. I understand that all three can be used to create abstract functions, but I am honestly a little confused about the difference between the three and when I'd use each one.
Anyone care to explain what each is used for and how they are different? Unfortunately my book is not very clear.
The basic idea is that all three are ways of applying some function to all the elements of a list.
Map is perhaps the simplest--you just apply the function to each element of the list. This is basically the same as a for-each loop in other languages:
(map (lambda (x) (+ x 1)) '(1 2 3))
=> (2 3 4)
Basically, map is like this: (map f '(1 2 3)) is the same as (list (f 1) (f 2) (f 3)).
Filter is also simple: the function acts like an arbiter, deciding whether to keep each number. Imagine a really picky eater going through a menu and whining about the things he won't eat ;)
(filter (lambda (x) (equal? x 1)) '(1 2 3))
=> (1)
Fold is the hardest to understand, I think. A more intuitive name would be "accumulate". The idea is that you're "combining" the list as you go along. There are some functions in ever day use that are actually folds--sum is a perfect example.
(foldr + 0 '(1 2 3))
=> 6
You can think of the fold as taking the function and putting it between each element in the list: (foldr + 0 '(1 2 3)) is the same as 1 + 2 + 3 + 0.
Fold is special because, unlike the other two, it usually returns a scalar value--something that was the element of the list rather than the list itself. (This isn't always true, but think of it this way for now anyway.)
Note that I may not have gotten every detail of the code perfect--I've only ever used a different, older implementation of Scheme so I might have missed some Racket details.
I can recommend these finger exercises (and the text that comes before):
http://htdp.org/2003-09-26/Book/curriculum-Z-H-27.html#node_idx_1464

Resources