Representing a queue as a procedure with local state - functional-programming

Section §2.1.3 at page 90 explains, with a very clear example, that first class functions in a language make functions themselves and data be the same thing looked at from different perspectives, or, to cite the book:
the ability to manipulate procedures as objects automatically provides the ability to represent compound data.
At page 266, exercise 3.22 from Section §3.3.2, proposes the following
Instead of representing a queue as a pair of pointers, we can build a queue as a procedure with local state. The local state will consist of pointers to the beginning and the end of an ordinary list. Thus, the make-queue procedure will have the form
(define (make-queue)
(let ((front-ptr ...)
(rear-ptr ...))
<definitions of internal procedures>
(define (dispatch m) ...)
dispatch))
Complete the definition of make-queue and provide implementations of the queue operations using this representation.
I easily came up with the following (I've used names the-list and last-pair instead of front-ptr and rear-ptr because I found it clearer, in this case):
(define (make-queue)
(let ((the-list '())
(last-pair '()))
(define (dispatch m)
(cond ((eq? m 'empty) (null? the-list))
((eq? m 'front) (if (null? the-list)
(error "can't take front of empty list")
(car the-list)))
((eq? m 'ins) (lambda (e)
(if (null? the-list)
(begin (set! the-list (list e))
(set! last-pair the-list))
(begin (set-cdr! last-pair (list e))
(set! last-pair (cdr last-pair))))
the-list))
((eq? m 'del) (begin
(if (null? the-list)
(error "can't delete from emtpy list")
(set! the-list (if (pair? the-list) (cdr the-list) '())))
the-list))
((eq? m 'disp) (display the-list)) ; added this for convenience
(else "error")))
dispatch))
(define (empty-queue? q) (q 'empty))
(define (front-queue q) (q 'front))
(define (insert-queue! q e) ((q 'ins) e))
(define (delete-queue! q) (q 'del))
(define (display-queue q) (q 'disp))
which seems to work pretty fairly well…
… except for one crucial point!
At the beginning of §3.3.2 the two desired mutators (that are part of the queue interface) are defined like this (my emphasis):
(insert-queue! <queue> <item>)
inserts the item at the rear of the queue and returns the modified queue as its value.
(delete-queue! <queue>)
removes the item at the front of the queue and returns the modified queue as its value, signaling an error if the queue is empty before the deletion.
My solution doesn't abide by those parts of the definition, because both insert-queue! and delete-queue! are returning the-list, which is the bare list, an implementation detail of the queue interface. Indeed, my solution doesn't support things like these
(define q (make-queue)) ; ok
(insert-queue! (insert-queue! q 3) 4) ; doesn't work
(delete-queue! (delete-queue! q)) ; doesn't work
whereas I think it should.
I guess that the solution should see delete-queue! and insert-queue! return a mutated version of the dispatch function.
How do I do that?

No need for that. Simply define
(define (insert-queue! q e)
((q 'ins) e)
q)
(define (delete-queue! q)
(q 'del)
q)
The design is not clean though, as in, these queues are not persistent. The new version and the old share the same underlying buffer (list). There is no old version preserved anymore, just the current version.
So we don't return a new, modified queue; we return the same queue which has been mutated. Conceptually, that is. On a little bit lower level, we return the same dispatch procedure which is a part of the same closure which holds the same internal binding for the internal buffer, which has been mutated.
By the way, using the head sentinel trick, were you start with e.g. (list 1) instead of '(), usually leads to much simplified, clearer code.

Related

how to create an alist with initial values

I'm learning scheme (using guile) and I found the need to create an initial alist, with some keys and empty lists as their values. I was wondering what's the best practice when doing something like this. My goal is to keep this alist around so I can later add items to the lists. This is what I have now:
(define buckets
`((hourly . ())
(daily . ())
(monthly . ())
(yearly . ())))
However, this does not work when trying to assoc-set!, to append items to the list. This, however, works:
(define buckets
(acons 'hourly '()
(acons 'daily '()
(acons 'monthly '()
(acons 'yearly '() '())))))
Clearly not the best looking piece of code. Is there a more idiomatic way of building such an alist? Maybe I'm doing this completely wrong. The end goal is to have these buckets that I can refer to later in different parts of code by their key.
Thanks!
scheme#(guile-user)> (acons 'hourly '()
(acons 'daily '()
(acons 'monthly '()
(acons 'yearly '() '()))))
$2 = ((hourly) (daily) (monthly) (yearly))
is the same as
scheme#(guile-user)> '((hourly) (daily) (monthly) (yearly))
$3 = ((hourly) (daily) (monthly) (yearly))
scheme#(guile-user)> (equal? $2 $3)
$4 = #t
EDIT assoc-set! doesn't work in this case because these lists are not mutable. One way to achieve a mutable list while still shortening the way to define it is to use this expression instead:
(map list '(hourly daily montly yearly))
My answer is in Scheme but can easily be translated to guile
If you want an advanced solution you can take an approach which will give you an abstraction layer and easier data management once done.
Take a step into Object Modeling!
Depending on the behavior(the set of methods you will support) you'd like your object to have, it should generally look like this:
(define make-state-manager
(lambda()
(let ((data_lst '()))
(letrec
((get-lst (lambda (key) (assoc key data_lst)))
((get-data (lambda (key) (assoc-ref key data_lst)))
((add-item (lam ...)
... here you should have add-data , remove-data etc.
(action_n ....)
(dispatch (lambda (action)
(cond ((eq? action ’full-list) get-lst)
((eq? action ’value) get-data)
((eq? action ’add-to-list) add-item)
...
((eq? action ’action_n) func_n)
(else (error "Unknown request: ~s" action)))))
)
dispatch))
))
...)))
Usage:
>(define data_manager (make-state-manager))
> data_manager
> #<procedure... >
> ((data_manager 'add-data) 'hourly '())
> ((data_manager 'value) 'hourly)
> ()
> ((data_manager 'full-list) 'hourly)
> (hourly . ())
Explanation:
First let creates a local state, so that you can run
(define data_manager1 (make-state-manager))
(define data_manager2 (make-state-manager))
and they will have different scopes, the actions will not affect one another.
Then in letrec you define the object methods with your method names.
In the dispatch (which gets dispatched :) to the user) you set the method names that the user will use.
sources : my brain & this crazy book
if this blows your mind too hard - come back to it later...

Concatenate List of Characters Recursively in Common LISP

So I'm attempting to implement a Caesar cipher in LISP recursively, and I've got the basic functionality working. The problem is it returns a list of characters, and calling concatenate 'string on the return statement just returns the same list of characters plus a "". What am I doing wrong here?
(defun caesar (s n)
(if (null (concatenate 'list s))
'()
(cons
(code-char (+ n (char-code (car (concatenate 'list s)))))
(caesar (coerce (cdr (concatenate 'list s)) 'string) n)
)
)
)
The right approach to something like this is to do the conversion between string & list in a wrapper of some kind & then have the main function work on the list.
Here is an approach to doing that which uses some of the power and elegance of CL. This:
uses CLOS methods to do wrapping -- this will presumably make it ineligible for submission as homework, in case that is what it is, but is a good demonstration of how pretty CLOS can be I think, and is also how I would actually write something like this;
uses coerce in the wrapper method rather than concatenate to change types, since that's what it's for;
intentionally does not deal with some of the other problems of the original code around recursion & char-codes.
First of all here is a version which uses two methods: a wrapper method (defined in the generic function definition for convenience) and then the recursive method which does the work:
(defgeneric caesar (text n)
(:method ((text string) n)
;; if we're given a string just turn it into a list, then recurse
;; on the list & turn it back to a string (of the same type, hence
;; TYPE-OF).
(coerce (caesar (coerce text 'list) n) (type-of text))))
(defmethod caesar ((text list) n)
;; The recursive level (note this has various issues which are in
;; the original code & not addressed here
(if (null text)
'()
(cons (code-char (+ n (char-code (first text))))
(caesar (rest text) n))))
Secondly here is a slightly too-clever approach, using a special termination-on-null method. I would not recommend this, but it's a neat demonstration of the kind of thing CLOS can do.
(defgeneric caesar (text n)
(:method ((text string) n)
;; if we're given a string just turn it into a list, then recurse
;; on the list & turn it back to a string (of the same type, hence
;; TYPE-OF).
(coerce (caesar (coerce text 'list) n) (type-of text))))
(defmethod caesar ((text null) n)
;; termination
'())
(defmethod caesar ((text list) n)
;; The recursive level (note this has various issues which are in
;; the original code & not addressed here
(cons (code-char (+ n (char-code (first text))))
(caesar (rest text) n)))
I would be tempted to combine with-output-to-string and labels (for the recursive bit):
(defun caesar (s n)
(with-output-to-string (cipher)
(labels ((beef (s)
(when s
(princ <whatever> cipher)
(beef (rest s)))))
(beef (coerce s 'list)))))
Caveat: the above is thoroughly untested and simply typed into this message, so likely will not even compile. It just makes the suggestions more cncrete.

What does this self referencing code do?

What is this self reference for?
Could it be written in any other way?
Is there any advantage?
(defmacro sublet (bindings% &rest body)
(let ((bindings (let-binding-transform
bindings%)))
(setq bindings
(mapcar
(lambda (x)
(cons (gensym (symbol-name (car x))) x))
bindings))
`(let (,#(mapcar #'list
(mapcar #'car bindings)
(mapcar #'caddr bindings)))
,#(tree-leaves
body
#1=(member x bindings :key #'cadr)
(caar #1#)))))
It's just a way of reusing structure somewhere else. In the macro you have:
(tree-leaves body
#1=(member x bindings :key #'cadr)
(caar #1#))
Which is just a fancy way of writing:
(tree-leaves body
(member x bindings :key #'cadr)
(caar (member x bindings :key #'cadr)))
On the positive side if you correct a bug in the member form you'll fix it both places, but it's runs the same code twice so if member was expensive this wouldn't be the wise way to do it. However it is a macro, thus run at compile time, and member is fairly fast on mall lists (small == millions of elements or below) so I guess it won't matter if you read the references just as good as any other CL code. An alternative and perhaps more readable for other kind of lispers would be:
(let ((found (member x bindings :key #'cadr)))
(tree-leaves body found (caar found)))

Echo server in common lisp with cl-usocket

I am trying a simple echo server in common lisp (I use clisp). I've tried the example in http://rosettacode.org/wiki/Echo_server#Common_Lisp
The CLISP version (without usocket) works fine.
When I try the usocket version (with clisp) I get the following error:
* - The condition
CDR: :INPUT is not a list
occurred.
Thank you in advance for your replies,
Dimitris
I'm not sure of the answer, but I think this can be tracked down to wait-for-input and wait-for-input-internal. The function wait-for-input has the following definition (abbreviated):
(defun wait-for-input (socket-or-sockets &key timeout ready-only)
"Waits for one or more streams to become ready for reading from
the socket. When `timeout' (a non-negative real number) is
specified, wait `timeout' seconds, or wait indefinitely when
it isn't specified. A `timeout' value of 0 (zero) means polling. …"
(unless (wait-list-p socket-or-sockets)
(let ((wl (make-wait-list (if (listp socket-or-sockets)
socket-or-sockets (list socket-or-sockets)))))
(multiple-value-bind
(socks to)
(wait-for-input wl :timeout timeout :ready-only ready-only)
(return-from wait-for-input
(values (if ready-only socks socket-or-sockets) to)))))
(let* ((start (get-internal-real-time))
(sockets-ready 0))
(dolist (x (wait-list-waiters socket-or-sockets))
(when (setf (state x)
#+(and win32 (or sbcl ecl)) nil ; they cannot rely on LISTEN
#-(and win32 (or sbcl ecl))
(if (and (stream-usocket-p x)
(listen (socket-stream x)))
:read
nil))
(incf sockets-ready)))
;; the internal routine is responsibe for
;; making sure the wait doesn't block on socket-streams of
;; which theready- socket isn't ready, but there's space left in the
;; buffer
(wait-for-input-internal socket-or-sockets
:timeout (if (zerop sockets-ready) timeout 0))
(let ((to-result (when timeout
(let ((elapsed (/ (- (get-internal-real-time) start)
internal-time-units-per-second)))
(when (< elapsed timeout)
(- timeout elapsed))))))
(values (if ready-only
(remove-if #'null (wait-list-waiters socket-or-sockets) :key #'state)
socket-or-sockets)
to-result))))
Note that the last section calls wait-for-input-internal with
(wait-for-input-internal socket-or-sockets
:timeout (if (zerop sockets-ready) timeout 0))
Now, the name socket-or-sockets implies that its value may be a single socket or a list of sockets. However, let's take a look at the definition of wait-for-input-internal for CLISP (it's defined in the backend/<implementation>.lisp):
(defmethod wait-for-input-internal (wait-list &key timeout)
(with-mapped-conditions ()
(multiple-value-bind
(secs musecs)
(split-timeout (or timeout 1))
(dolist (x (wait-list-%wait wait-list))
(setf (cdr x) :INPUT))
(let* ((request-list (wait-list-%wait wait-list))
(status-list (if timeout
(socket:socket-status request-list secs musecs)
(socket:socket-status request-list)))
(sockets (wait-list-waiters wait-list)))
(do* ((x (pop sockets) (pop sockets))
(y (cdr (pop status-list)) (cdr (pop status-list))))
((null x))
(when (member y '(T :INPUT))
(setf (state x) :READ)))
wait-list))))
There are two uses of :INPUT there. It appears that each element of the wait-list is supposed to be a cons whose cdr contains some sort of state. Perhaps wait-for-input is getting called with a single socket (after all, the argument name is socket-or-sockets, and when wait-for-input-internal is called, it's expecting a list. That could lead to the latter getting (<something> . :INPUT) when expecting ((<something . :INPUT)). I'm not sure, though. In any case, though, the error is coming from somewhere around here.

Avoiding mutable state when I need to store (current-seconds) multiple times

I've put together the following rudimentary stopwatch in Racket (just learning now, the final aim is a pomodoro-timer).
#lang racket
(define start-time 0)
(define end-times '())
(define (start);; stores start-time
(set! start-time (current-seconds)))
(define (lap);; stores "laps" in list
(set! end-times (cons (current-seconds) end-times)))
(define (stop);; stores final time, displays lap-times in h, m, s and resets end-times
(begin
(set! end-times (cons (current-seconds) end-times))
(display
(reverse
(map (lambda (an-end)
(let ((the-date (seconds->date(- an-end start-time))))
(list
(sub1(date-hour the-date))
;; sub1 is needed because (date-hour(seconds->date 0) = 1
(date-minute the-date)
(date-second the-date)))) end-times)))
(set! end-times '())
))
While this does exactly what it should, I was wondering how I could avoid mutable state. If I follow HTDP, this is the kind of situation where mutable state is warranted, but after browsing Wadler's "Monads for Functional Programming", I'm still curious about how I could do without set!.
I know that to make it functional, I should add arguments to my functions. For instance, start would become
(define (start [now (current-seconds)])
now)
and a similar approach could work with lap and stop.
Still, while I know that after adding additional arguments to restore functionality, I should also pass arguments rather than storing values in variables, I don't see how in this case I can leverage this to avoid set! as well.
Update: Since all three answers below are highly valuable (thanks!), I didn't mark any of them as the unique correct one. Below is the minimal solution to my initial question. It is a combination of the loop-proposal of #Metaxal, with the example-usage of #Greg Hendershott.
#lang racket
(define (run)
(displayln "Enter 'lap' or 'quit':")
(let loop ([t0 (current-seconds)] [times '()])
(match (read-line)
["quit" (reverse
(map (lambda (x)
(let ((the-date (seconds->date x)))
(list
(sub1(date-hour the-date))
(date-minute the-date)
(date-second the-date)))) times))]
["lap" (loop t0 (cons (- (current-seconds) t0) times))]
[_ (loop t0 times)])))
What will likely happen in the following of your program is that you will have a loop.
Then this loop can be a function that takes as input the whole current state, and when you want to update its state, just call the loop again with the new state (you may also call the loop again with the same exact state of course).
Simplified example:
(define (loop [t0 (current-seconds)] [times '()])
;; ... do things here, possibly depending on user input ...
;; then loop with a new state:
(cond [<some-start-condition> (loop (current-seconds) '())]
[<some-lap-condition> (loop t0 (cons (- (current-seconds) t0) times))]
[<some-stop-condition> times])) ; stop, no loop, return value
This certainly changes the approach to your design though.
It's harder to use this approach when designing GUI programs, because the event loop often prevents you from (or makes it difficult) passing values from one event to the next.
However, in Racket, there is (the pedagogical, but still very good) big-bang that is made just for that.
In this case using set! is justified and hard to avoid, because we must "remember" state between invocations of the procedures. What we can do is improving the encapsulation of state, by hiding the variables that change inside a procedure and using a message dispatcher for accessing the procedures that refer to the mutable state. This is very similar to what we do with object-oriented programming, but only lambdas are required to implement it!
(define (make-timer)
; the "attributes" of the object
(let ([start-time 0]
[end-times '()])
; the "methods" of the object
(define (start)
(set! start-time (current-seconds)))
(define (lap)
(set! end-times (append end-times (list (current-seconds)))))
(define (stop)
(lap)
(display
(map (lambda (an-end)
(let ((the-date (seconds->date (- an-end start-time))))
(list
(sub1 (date-hour the-date))
(date-minute the-date)
(date-second the-date))))
end-times))
(set! end-times '()))
; return a dispatch procedure
(lambda (msg)
(case msg
((start) (start)) ; call the start procedure defined above
((lap) (lap)) ; call the lap procedure defined above
((stop) (stop)) ; call the stop procedure defined above
(else (error "unknown message:" msg))))))
I took the liberty of modifying some of your procedures to make them a bit simpler. Here's how we would use the timer object we just created:
(define timer (make-timer))
(timer 'start)
(sleep 1)
(timer 'lap)
(sleep 1)
(timer 'lap)
(sleep 1)
(timer 'lap)
(sleep 1)
(timer 'stop)
=> ((18 0 1) (18 0 2) (18 0 3) (18 0 4))
This technique is called "message passing", learn more about it in the wonderful SICP book.
For a simple example like this, I would probably do what #Metaxal
suggested.
However another approach is that you could explicitly define the state
as a struct:
(struct state (start-time end-times))
Then change the start, lap, and stop to be functions on state:
;; start : -> state
;; stores start-time
(define (start)
(state (current-seconds) '()))
;; lap : state -> state
;; stores "laps" in list
(define (lap st)
(match-define (state start-time end-times) st)
(state start-time
(cons (current-seconds) end-times)))
;; stop : state -> list
;; stores final time, displays lap-times in h, m, s
(define (stop st)
(match-define (state start-time end-times*) st)
(define end-times (cons (current-seconds) end-times*))
(reverse
(map (lambda (an-end)
(let ((the-date (seconds->date(- an-end start-time))))
(list
(sub1(date-hour the-date))
;; sub1 is needed because (date-hour(seconds->date 0) = 1
(date-minute the-date)
(date-second the-date)))) end-times)))
As in #Metaxal's answer, your "main loop" needs to handle the state and "thread" it through the functions as appropriate:
Example usage:
(define (run)
(displayln "Enter 'lap' or 'quit':")
(let loop ([st (start)])
(match (read-line)
["quit" (stop st)]
["lap" (loop (lap st))]
[_ (loop st)])))
Whereas #Óscar López's answer shows a style of OOP as explained in SICP.
A nice thing about Racket (and Scheme) is that you can choose whatever approach on the spectrum you think best fits the problem at hand, and your taste -- simple imperative, OOP imperative, pure functional.

Resources