Recursively peek a map to get its values in Clojure - recursion

I'm trying to write a function which will recursively pop a map in order to get a value out, one at a time.
The following is what I've got so far..
(defrecord Stoptest [&args])
(def test (Stoptest. [:c101 :main-office :a1]))
(defn stopPop [x]
(peek (-> x :&args))
(recur(peek(rest x))))
(stopPop test)
I get an error saying the following:
clojure.lang.LazySeq cannot be cast to clojure.lang.IPersistentStack
What's causing this issue?
Cheers

rest returns not a vector but a lazy seq. The error appears when you try to peek on in:
(peek (seq [1 2 3]))
;; gives the same error
The problem happens here because you have different type objects on each step of recursion. On the top, you have Stoptest instance. Next, you have a lazy sequence that behaves in other way.
I don't see any reason here to wrap your vector into a typed record. You can always iterate on the vector easily.

Related

SBCL-specific declaim

SBCL generates spurious style warnings about undefined functions. (The functions are defined, just later in the file.) I want to solve this problem once and for all. Fortunately, there is a way to do this:
(declaim (sb-ext:muffle-conditions style-warning))
The downside is that CCL, for obvious reasons, barfs on a program containing the above. I try to solve this problem with a conditional:
(#+sbcl (declaim (sb-ext:muffle-conditions style-warning)))
but now SBCL is unhappy: "illegal function call".
How do you put such a declaim into a portable program?
Note that while the existing answer is right, disabling warnings is not a good practice. In your case, it is probably not necessary.
Common Lisp has a notion of compilation unit, where multiple definitions are grouped together. This gives a chance for the compiler/interpreter to take care of cross-references among functions (an interpreter could collect warnings and keep only those that are not found later, for example).
For example, in file #P"/tmp/foo.pl":
(defun mut-rec-foo (x)
(when (plusp x)
(mut-rec-bar (1- x))))
(defun mut-rec-bar (x)
(print x)
(mut-rec-foo (1- x)))
Do not evaluate anything in the file; instead do:
(compile-file #P"/tmp/foo.pl")
; compiling (DEFUN MUT-REC-FOO ...)
; compiling (DEFUN MUT-REC-BAR ...)
; /tmp/foo.fasl written
; compilation finished in 0:00:00.002
No warning. You can then call (load #P"/tmp/foo.fasl") to have the definitions in your current lisp environment, without warnings.
Typically, ASDF and by extension Quicklisp use COMPILE-FILE, so your problem should disappear as soon as you bundle your files into a system.
You can also do:
(with-compilation-unit ()
(defun mut-rec-foo/bis (x)
(when (plusp x)
(mut-rec-bar/bis (1- x))))
(defun mut-rec-bar/bis (x)
(print x)
(mut-rec-foo/bis (1- x))))
Evaluating the whole block shows no warning for *EVALUATOR-MODE* being both :COMPILE or :INTERPRET.
What you witnessed happens when you evaluate each expression one after the other (or maybe one region after another one). There, the compiler has no way to know that the function already exists. Silencing the warning is the worse option, because you might actually have made an error.
If you know in advance that a function will exist, but not in your compilation unit (maybe it is only defined at runtime), the you can declaim that fact, as follows:
(declaim (ftype function my-function))
The above says that my-function must be assumed to be fbound to an object of type function. You could also give more information by refining what kind of function you claim it to be:
(declaim (ftype (function (number) (values string &optional)) num-to-string))
... for a function that accepts a number and returns exactly one value, a string.
(declaim (ftype (function () nil) forever-loop))
... for a function that accepts nothing and never return a value (loop or signals an error).
Omit the outer pair of parentheses:
#+sbcl (declaim (sb-ext:muffle-conditions style-warning))
As you are using declaim, I assume, that the declaration appears at the top-level of a compilation unit. If you need to group multiple top-level statements, you can wrap them all with a progn (which doesn't change the "top-level"-ness).
The reason SBCL did complain is, that its reader reads
((declaim (sb-ext:muffle-conditions style-warning)))
(as the :SBCL feature is present), which is simply a syntax error. CCL does not complain, because its reader reads
()
which is simply another way to spell nil.

Recursive Loop in Clojure via Macro is throwing me errors

I've been trying to write a recursive loop in clojure that will print me out the very last number in the list. The point is not that I need to get the last number (for which I'm sure there's a built in function for that) but that I want to better understand recursion and macros in clojure. So I have this macro...
(defmacro loop-do [the-list]
`(if (= (count '~the-list) 1)
(println (first '~the-list))
(loop-do (rest '~the-list))))
But I get a stackoverflow error. What am I doing wrong?
How will people use your macro?
Somewhere, someone will call:
(loop-do list)
As a piece of code, those are only two symbols in a list. The first one is recognized as your macro, and the second one, list, is a symbol that represents a variable that will be bound at runtime. But your macro only knows that this is a symbol.
The same goes for:
(loop-do (compute-something))
The argument is a form, but you do not want to get the last element of that form, only the last element of the list obtained after evaluating the code.
So: you only know that in your macro, the-list will be bound to an expression that, at runtime, will have to be a list. You cannot use the-list as-if it was a list itself: neither (count 'list) nor (count '(compute-something)) does what you want.
You could expand into (count list) or (count (compute-something)), though, but the result would only be computed at runtime. The job of the macro is only to produce code.
Recursive macros
Macros are not recursive: they expand into recursive calls.
(and a b c)
might expand as:
(let [a0 a] (if a0 a0 (and b c)))
The macroexpansion process is a fixpoint that should terminate, but the macro does not call itself (what would that mean, would you expand the code while defining the macro?). A macro that is "recursive" as-in "expands into recursive invocations" should have a base case where it does not expand into itself (independently of what will, or will not, happen at runtime).
(loop-do x)
... will be replaced by:
(loop-do (rest 'x))
... and that will be expanded again.
That's why the comments say the size actually grows, and that's why you have a stackoverflow error: macroexpansion never finds a fixpoint.
Debugging macros
You have a stackoverflow error. How do you debug that?
Use macroexpand-1, which only performs one pass of macroexpansion:
(macroexpand-1 '(loop-do x))
=> (if (clojure.core/= (clojure.core/count (quote x)) 1)
(clojure.core/println (clojure.core/first (quote x)))
(user/loop-do (clojure.core/rest (quote x))))
You can see that the generated code still contains a call to usr/loop-do , but that the argument is (clojure.core/rest (quote x)). That's the symptom you should be looking for.

common lisp's let binds, not executes?

In this code
(defun foo ()
. . .
(let ((bar (foo)))
(if bar
. . .)))
in the let line, let is only binding, right? It doesn't actually run foo. I assume foo is run (recursively) for the first time in the if statement, correct? If what I assume is correct, is there a way to have let actually execute foo and then assign the results to bar?
There's an answer that shows an example that illustrates the behavior of let. However, an example via an implementation doesn't answer conclusively whether it's supposed to behave that way, or whether implementations are free to do different things, or whether there's a bug in the implementation. To know what's supposed to happen, you need to check the documentation. Fortunately, the Common Lisp HyperSpec is freely available online. The documentation for let says:
Special Operator LET, LET*
let and let* create new variable bindings and execute a series of
forms that use these bindings. let performs the bindings in parallel
and let* does them sequentially.
The form
(let ((var1 init-form-1)
(var2 init-form-2)
...
(varm init-form-m))
declaration1
declaration2
...
declarationp
form1
form2
...
formn)
first evaluates the expressions init-form-1, init-form-2, and so on,
in that order, saving the resulting values. Then all of the variables
varj are bound to the corresponding values; each binding is lexical
unless there is a special declaration to the contrary. The expressions
formk are then evaluated in order; the values of all but the last are
discarded (that is, the body of a let is an implicit progn).
Thus, all the forms are evaluated (executed), then the results are bound the values, and then the forms in the body are evaluated.
In the example you provided, foo is evaluated and then assigned to bar. You can test this by simply evaluating something like:
(let ((foo (+ 1 2)))
(if (= foo 3)
foo
nil))
; => 3
cf. PCL: Syntax and Semantics or Lispdoc.
Edit
As #paulo-madeira brought up in the comments, this is not enough to test, since you don't know when each one was evaluated. See his comment for a way to test it using FORMAT. Anyway, the takeaway is, the LET you propose evaluates foo and assigns it to bar, which means your function foo is defined in terms of itself, which means you're up to no good.

Tail Recursions in erlang

I'm learning Erlang from the very basic and have a problem with a tail recursive function. I want my function to receive a list and return a new list where element = element + 1. For example, if I send [1,2,3,4,5] as an argument, it must return [2,3,4,5,6]. The problem is that when I send that exact arguments, it returns [[[[[[]|2]|3]|4]|5]|6].
My code is this:
-module(test).
-export([test/0]).
test()->
List = [1,2,3,4,5],
sum_list_2(List).
sum_list_2(List)->
sum_list_2(List,[]).
sum_list_2([Head|Tail], Result)->
sum_list_2(Tail,[Result|Head +1]);
sum_list_2([], Result)->
Result.
However, if I change my function to this:
sum_list_2([Head|Tail], Result)->
sum_list_2(Tail,[Head +1|Result]);
sum_list_2([], Result)->
Result.
It outputs [6,5,4,3,2] which is OK. Why the function doesn't work the other way around([Result|Head+1] outputing [2,3,4,5,6])?
PS: I know this particular problem is solved with list comprehensions, but I want to do it with recursion.
For this kind of manipulation you should use list comprehension:
1> L = [1,2,3,4,5,6].
[1,2,3,4,5,6]
2> [X+1 || X <- L].
[2,3,4,5,6,7]
it is the fastest and most idiomatic way to do it.
A remark on your fist version: [Result|Head +1] builds an improper list. the construction is always [Head|Tail] where Tail is a list. You could use Result ++ [Head+1] but this would perform a copy of the Result list at each recursive call.
You can also look at the code of lists:map/2 which is not tail recursive, but it seems that actual optimization of the compiler work well in this case:
inc([H|T]) -> [H+1|inc(T)];
inc([]) -> [].
[edit]
The internal and hidden representation of a list looks like a chained list. Each element contains a term and a reference to the tail. So adding an element on top of the head does not need to modify the existing list, but adding something at the end needs to mutate the last element (the reference to the empty list is replaced by a reference to the new sublist). As variables are not mutable, it needs to make a modified copy of the last element which in turn needs to mutate the previous element of the list and so on. As far as I know, the optimizations of the compiler do not make the decision to mutate variable (deduction from the the documentation).
The function that produces the result in reverse order is a natural consequence of you adding the newly incremented element to the front of the Result list. This isn't uncommon, and the recommended "fix" is to simply list:reverse/1 the output before returning it.
Whilst in this case you could simply use the ++ operator instead of the [H|T] "cons" operator to join your results the other way around, giving you the desired output in the correct order:
sum_list_2([Head|Tail], Result)->
sum_list_2(Tail, Result ++ [Head + 1]);
doing so isn't recommended because the ++ operator always copies it's (increasingly large) left hand operand, causing the algorithm to operate in O(n^2) time instead of the [Head + 1 | Tail] version's O(n) time.

Scheme: Changing the reader to accept i+j+k notation

Basically what I am trying to do with this is alter the reader so that it will accept vector notation like i+j+k. The goal of this is to convert things that look like vectors into strings while not affecting anything else. For instance, if someone typed in abc it would still throw an error message, but if someone typed in i+j+k would return "i+j+k".
This is what I have so far:
#lang racket/base
(require syntax/strip-context)
(provide (except-out (all-from-out racket/base)
#%top)
(rename-out (#%my-top #%top)))
(require (for-syntax racket/base))
(define-syntax (#%my-top stx)
(syntax-case stx ()
[(_ . quat)
#' (test (#%datum . quat))]
[(_ . other)
(syntax/loc stx
(#%datum . other))]))
(define (quat? testExp)
(regexp-match-exact? #rx"([+-]?([0-9]+[i-k]?|[0-9]*[i-k])([+-]([0-9]+[i-k]?|[0-9]*[i-k]))*)" testExp))
(define (test x)
(cond ((quat? (symbol->string x)) (symbol->string x))
(else (strip-context x))))
This code does work in converting vector notation into strings. i+j+k successfully becomes "i+j+k". But the problem is that it converts EVERYTHING into syntax first, and I cannot get it back to whatever it originally was. For example, abc will become 'abc and it wont throw an error like it normally should. I have no idea how to get around this. I originally thought all I needed was a simple change to that else statement on the final line, but I cannot get anything to work. I am beginning to think I need to try a completely new approach. Any help would be greatly appreciated.
Also, it should be noted that you have to have this code in one file, I called mine parse.rkt, and perform your tests in a separate file that only has
#lang racket
(require "parse.rkt")

Resources