I have a bi-dimensional array and I want to change the value at the i, j entry. Naturally, I would go with (setf (aref foo i j) 3).
But my spider sense tells me that I use dozens of memory and processing, because if fell I am deleting and creating the array, in an interation, once, and once again.
How should I do?
#jkiiski is right in his comment. You are not creating copies of the array. You are modifying it in place.
Related
I'm trying to write a snippet whose inputs (tab-stop fields) are two numbers, and which returns their sum. But I don't know how to reference the values of both fields at the same time, and it seems like I can't reference the values of the tab-stop within embedded elisp code.
Here is what I tried:
First number: $1
Second number: $2
Sum of two numbers: `(+ (string-to-number $1) (string-to-number $2))`
But when I expand the snippet, the text [yas] elisp error! appears where the sum should go. What am I doing wrong?
joaotavora recently pointed out that this can be done using yas-field-value:
First number: ${1:0}
Second number: ${2:0}
Sum of two numbers: ${2:$(+ (string-to-number (or (yas-field-value 1) "0")) (string-to-number (or yas-text "0")))}
and sorry for the confusion. According to the official snippet writing guide, what you are looking for is called a mirror. Unfortunately, a mirror can only mirror a single variable, so you seem to be out of luck.
This is probably because yasnippet needs to know which mirrors to update when you type a field. (It doesn't want to update them all, because that could be costly), so it needs a way of determining which mirrors are affected by which fields. If it allowed arbitrary substitutions, that would be impossible to determine. (A simple keyword search isn't enough because the variable could be hidden behind metaprogramming).
I'm trying to implement a Towers of Hanoi recursively with Common Lisp. I know what the recursive calls are and how they work, but I'm just lost with how I would go about moving something from the end of one list, to the end of another list. I was trying to do some research on how to do this, but I couldn't find anything online.
Any help would be greatly appreciated.
Thanks!
You can remove the last element of a list with butlast, get last element with last, and you cat append a list to another list with append (you just cons your element to be added so that it's a one element list). Working on the end of lists in CL are not optimal as every function needs to traverse the list in order to find the last one, but it is done when you need to add/remove in both ends.
With Tower of Hanoi you are stacking disks on top of each other and the last one put is the first one out. In Common Lisp (in fact any Lisp cousin) you can easily add to front and remove from front with doing (cdr pole-a) in the recursive call to remove the top element from pole-a and add to pole-b with (cons (car pole-a) pole-b) in the recursive call.
I imagine you need this to actually be able to see which disk is moved in each stage, since you need no such structure to calculate the moves needed. In such a scenario you only need the names of the poles and the level the recursion and the number of disks you want to move in this round.
Is it good style to use cons for pairs of things or would it be preferable to stick to lists?
like for instance questions and answers:
(list
(cons
"Favorite color?"
"red")
(cons
"Favorite number?"
"123")
(cons
"Favorite fruit?"
"avocado"))
I mean, some things come naturally in pairs; there is no need for something that can hold more than two, so I feel like cons would be the natural choice. However, I also feel like I should be sticking to one thing (lists).
What would be the better or more accepted style?
What you have there is an association list (alist). Alist entries are, indeed, often simple conses rather than lists (though that is a matter of preference: some people use lists for alist entries too), so what you have is fine. Though, I usually prefer to use literal syntax:
'(("Favorite color?" . "red")
("Favorite number?" . "123")
("Favorite fruit?" . "avocado"))
Alists usually use a symbol as the key, because symbols are interned, and so symbol alists can be looked up using assq instead of assoc. Here's how it might look:
'((color . "red")
(number . "123")
(fruit . "avocado"))
The default data-structure for such case should be a HASH-TABLE.
An association list of cons pairs is also a possible variant and was widely used historically. It is a valid variant, because of tradition and simplicity. But you should not use it, when the number of pairs exceeds several (probably, 10 is a good threshold), because search time is linear, while in hash-table it is constant.
Using a list for this task is also possible, but will be both ugly and inefficient.
You would need to decide for yourself based upon circumstances. There isn't a universal answer. Different tasks work differently with structures. Consider the following:
It is faster to search in a hash-table for keys, then it is in the alist.
It is easier to have an iterator and save its state, when working with alist (hash-table would need to export all of its keys as an array or a list and have a pointer into that list, while it is enough to only remember the pointer into alist to be able to restore the iterator's state and continue the iteration.
Alist vs list: they use the same amount of conses for even number of elements, given all other characters are atoms. When using lists vs alists you would have to thus make sure there isn't an odd number of elements (and you may discover it too late), which is bad.
But there are a lot more functions, including the built-in ones, which work on proper lists, and don't work on alists. For example, nth will error on alist, if it hits the cdr, which is not a list.
Some times certain macros would not function as you'd like them to with alists, for example, this:
(destructuring-bind (a b c d)
'((100 . 200) (300 . 400))
(format t "~&~{~s~^,~}" (list a b c d)))
will not work as you might've expected.
On the other hand, certain procedures may be "tricked" into doing something which they don't do for proper lists. For instance, when copying an alist with copy-list, only the conses, whose cdr is a list will be copied anew (depending upon the circumstances this may be a desired result).
Ok I need some help with thinking through this conceputally.
I need to check if a list and another list is structurally equal.
For example:
(a (bc) de)) is the same as (f (gh) ij)), because they have the same structure.
Now cleary the base case will be if both list are empty they are structurally equal.
The recursive case on the other hand I'm not sure where to start.
Some ideas:
Well we are not going to care if the elements are == to each other because that doesn't matter. We just care in the structure. I do know we will car down the list and recursively call the function with the cdr of the list.
The part that confuses me is how do you determine wheter an atom or sublist has the same structure?
Any help will be appreciated.
You're getting there. In the (free, online, excellent) textbook, this falls into section 17.3, "Processing two lists simultaneously: Case 3". I suggest you take a look.
http://www.htdp.org/2003-09-26/Book/curriculum-Z-H-1.html#node_toc_node_sec_17.3
One caveat: it looks like the data definition you're working with is "s-expression", which you can state like this:
;; an s-expression is either
;; - the empty list, or
;; - (cons symbol s-expression), or
;; - (cons s-expression s-expression)
Since this data definition has three cases, there are nine possibilities when considering two of them.
John Clements
(Yes, you could reduce the number of cases by embedding the data in the more general one that includes improper lists. Doesn't sound like a good idea to me.)
I note that Scheme and Lisp (I guess) support circular lists, and I have used circular lists in C/C++ to 'simplify' the insertion and deletion of elements, but what are they good for?
Scheme ensures that they can be built and processed, but for what?
Is there a 'killer' data structure that needs to be circular or tail-circular?
Saying it supports 'circular lists' is a bit much. You can build all kinds of circular data structures in Lisp. Like in many programming languages. There is not much special about Lisp in this respect. Take your typical 'Algorithms and Datastructure' book and implement any circular data structure: graphs, rings, ... What some Lisps offer is that one can print and read circular data structures. The support for this is because in typical Lisp programming domains circular data structures are common: parsers, relational expressions, networks of words, plans, ...
It is quite common that data structures contain cycles. Real 'circular lists' are not that often used. For example think of a task scheduler which runs a task and after some time switches to the next. The list of tasks can be circular so that after the 'last' task the scheduler takes the 'first' task. In fact there is no 'last' and 'first' - it is just a circular list of tasks and the scheduler runs them without end. You could also have a list of windows in a window system and with some key command you would switch to the next window. The list of windows could be circular.
Lists are useful when you need a cheap next operation and the size of the data structure is unknown in advance. You can always add another node to the list or remove a node from a list. Usual implementations of lists make getting the next node and adding/removing an item cheap. Getting the next element from an array is also relatively simple (increase the index, at the last index go to the first index), but adding/removing elements usually needs more expensive shift operations.
Also since it is easy to build circular data structures, one just might do it during interactive programming. If you then print a circular data structure with the built-in routines it would be a good idea if the printer can handle it, since otherwise it may print a circular list forever...
Have you ever played Monopoly?
Without playing games with counters and modulo and such, how would you represent the Monopoly board in a computer implementation of the game? A circular list is a natural.
For example a double linked list data structure is "circular" in the Scheme/LISP point of view, i.e. if you try to print the cons-structure out you get backreferences, i.e. "cycles". So it's not really about having data structures that look like "rings", any data structure where you have some kind of backpointers is "circular" from the Scheme/LISP perspective.
A "normal" LISP list is single linked, which means that a destructive mutation to remove an item from inside the list is an O(n) operation; for double linked lists it is O(1). That's the "killer feature" of double linked lists, which are "circular" in the Scheme/LISP context.
Adding and removing elements to the beginning of a list is cheap. To
add or remove an element from the end of a list, you have to traverse
the whole list.
With a circular list, you can have a sort of fixed-length queue.
Setup a circular list of length 5:
> (import (srfi :1 lists))
> (define q (circular-list 1 2 3 4 5))
Let's add a number to the list:
> (set-car! q 6)
Now, let's make that the last element of the list:
> (set! q (cdr q))
Display the list:
> (take q 5)
(2 3 4 5 6)
So you can view this as a queue where elements enter at the end of the list and are removed from the head.
Let's add 7 to the list:
> (set-car! q 7)
> (set! q (cdr q))
> (take q 5)
(3 4 5 6 7)
Etc...
Anyways, this is one way that I've used circular-lists.
I use this technique in an OpenGL demo which I ported from an example in the Processing book.
Ed
One use of circular lists is to "repeat" values when using the srfi-1 version of map. For example, to add val to each element of lst, we could write:
(map + (circular-list val) lst)
For example:
(map + (circular-list 10) (list 0 1 2 3 4 5))
returns:
(10 11 12 13 14 15)
Of course, you could do this by replacing + with (lambda (x) (+ x val)), but sometimes the above idiom can be handier. Note that this only works with the srfi-1 version of map, which can accept lists of different sizes.