PicoLisp Explored: The fifo function

Search for a command to run...

No comments yet. Be the first to comment.
In this series, some more advanced features of PicoLisp will be explained that have not been covered in the beginner's tutorial.
"The best time to plant a tree was 25 years ago. The second-best time to plant a tree is today." (Eliud Kipchoge)
In our previous post, we introduced how to utilize Discrete Event Simulation (DES) in PicoLisp. Now, let's explore another application: a railroad model simulation that includes tracks and trains. The visualization is ASCII-based, so feel free to unl...

The Dining Philosophers

In this post, we will introduce the concept of co-routines and how they are handled in PicoLisp. This will be the foundation for the subsequent posts on Discrete Event Simulation and finally a couple of examples, including an ASCII model railway simu...

One of the many nice things of PicoLisp is that it comes with a built-in database. This makes it easy to collect and store our own data, for example via a mobile app. But not all data is best represented in tables and lists: sometimes a colorful litt...

In the last two posts, we have built a little app that shows the current location and displays the nearest ice cream shops: https://picolisp-explored.com/an-openstreetmap-app-written-in-picolisp-pt-1 https://picolisp-explored.com/an-openstreetmap-ap...

Today we will discuss an interesting function called fifo: First-In-First-Out.
As always in "PicoLisp Explored", we will check the documentation and the internal representation of the data to understand what is happening.
The FIFO principle is nothing special or fancy - it just says that "old" items should be used first. Think of a supermarket where the employee always puts the new items behind the old ones.
Obviously the same principle is also possible with data, for example a task list, where the older items should be done first. We can create such a list and take out its items using the fifo function.
fifo listLet's check the documentation of the fifo function.
(fifo 'var ['any ..]) -> anyImplements a first-in-first-out structure using a circular list. When called with
anyarguments, they will be concatenated to end of the structure. Otherwise, the first element is removed from the structure and returned.
Sounds pretty straightforward - let's create a simple to-do List using the fifo function. We need to define the list variable, for example ToDo, followed by its items.
: (fifo 'ToDo "buy groceries")
-> "buy groceries"
: (fifo 'ToDo "make dinner")
-> "make dinner"
: (fifo 'ToDo "clean up the kitchen")
-> "clean up the kitchen"
Now let's check the content of ToDo.
: ToDo
-> ("clean up the kitchen" "buy groceries" "make dinner" .)
What do you think? Well, we have all the items, but isn't it a bit strange that the list is starting with "clean up the kitchen", ? Isn't that supposed to be the last point?
Actually, it is not. The point is that the list is circular (note the . at the end!). Internally, or ToDo list looks something like this:

We can confirm this by checking the car and cdr of fifo.
: (car ToDo)
-> "clean up the kitchen"
: (cdr ToDo)
-> ("buy groceries" "make dinner" "clean up the kitchen" .)
As you can see, (cdr ToDo) delivers us the output that we expected - all list items in chronological order. This is because of the circular nature of the list.
As the docs told us, we just need to write (fifo <var>) to get out the next item. After that, there will be only two more items in our list.
: (fifo 'ToDo)
-> "buy groceries"
: (cdr ToDo)
-> ("make dinner" "clean up the kitchen" .)
Imagine you have a really super large list. We add new items to the beginning, and always take out the item at the end. What does that mean?
If the list is not circular, we would need to traverse the whole list down and basically jump from pointer to pointer until we reach the last item. This means the cost of this operation increases linearly with the list length.
On the other hand, with ourfifo function, we can do it in constant time: No matter how long the list, we can always get the last item by (cadr list).
Well, that's basically all there is to say about the fifo function.
If this post was too easy for you, here is a little homework: How can we implement the level-inorder function of the binary tree traversal?
1
/ \
/ \
/ \
2 3
/ \ /
4 5 6
/ / \
7 8 9
Expected output: 1 2 3 4 5 6 7 8 9
Hint 1: Use the fifo function.
Hint 2: No recursion needed.
Photo by Franki Chamaki on Unsplash
https://software-lab.de/doc/index.html