I think my code is on the right track, but I am either missing something or overlooking the solution. I want to remove an element from the list and it is somewhat doing it but not in the way that I want it. Here is my code:
(defn removeLetter [x y]
(remove #{y} (list x))
)
(println (removeLetter '(w x y z) 'w))
This outputs ((w x y z)) when I want it to output (x y z).
How can I fix my code?
list doesn't convert its argument into a list - instead, it accepts any amount of arguments and returns a list containing those values.
You can simply replace (list x) with just x and it should work then.
Related
For an homework, I am trying to iterate through the list and make an if statement to each of the elements I encounter in Common Lisp.
Most of my problems come from me not knowing the syntax very well though.
Here is what I am trying to do:
*lst* is for example (1 4 2 6 4 7 2 4)
(setq finalList())
(loop for x in lst
(if ((< x 5) && (not(equal(x nil)))) ; IF x < 5 and x != nil
(append lst x) ; THEN STATEMENT
(princ "Skip") ; ELSE STATMENT
)
That logically should have done it, however, I am possibly wrong with my syntax
(If I forgot extra colon here, judge if as pseudo code, thanks)
How to iterate through the list and make an if else statements to each of the elements I encounter?
Errors
Syntax: instead of infix &&, you need prefix and
loop requires the keyword do before the if form.
append is non-destructive, so if you did not assign its return value to a variable, you did nothing.
Lisp function call syntax is (func arg1 arg2 ...) and not (func (arg1 arg2 ...)) as you use in your equal call.
The order of conditionals matters: if x is nil, then (< x 5) will signal an error, so you need to check x before the comparison.
The long and complicated (not (equal x nil)) is actually equivalent to x.
Unlike in other languages (e.g., C and Python), in Lisp parens matter, e.g., foo, (foo), ((foo)) are three very different things and can never be used interchangeably.
Solutions
Use the Loop micro-language
The loop facility is perfect as it has the if and collect clauses:
(loop for x in lst
if (and x (< x 5))
then collect x
else (print x))
Note: this does not really look like Lisp, so you might want to steer clear of loop while you are learning the language.
Use Functional Programming
(remove-if-not (lambda (x) (and x (< x 5))) lst)
Note: this does not print the dropped elements, I am sure you had the print clause for debugging only anyway.
Use Iteration
(let ((res ()))
(dolist (x lst (nreverse res))
(when (and x (< x 5))
(push x res))))
Note: I use nreverse: since we construct the result list ourselves, the is no reason not to use the destructive version or reverse.
I have a list like that -> (define l '(at1 at2 at3)) where at1 is the name of a function. When I try to put that value as the name of a function (i.e. (at1 value1 value2)), I obtain this:
application: not a procedure;
expected a procedure that can be applied to arguments
because at1 is a list ('valueofat1). I'm trying to use apply and list->string, but both aren't work. What am I doing wrong? How can I use the value of a list in a given position as a function?
If you definitely want to use a list of symbols representing function names you can use apply and eval, but beware: eval is evil and you should avoid using it!
; some functions
(define (at1 x y) (+ x y))
(define (at2 x y) (- x y))
(define (at3 x y) (* x y))
; a list of symbols named like the functions
(define lst '(at1 at2 at3))
; operands
(define value1 30)
(define value2 12)
; obtain evaluation namespace
(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))
; apply the first function from the list of function names
(apply (eval (car lst) ns) (list value1 value2))
^ ^
evaluate operator list of operands
The above will return 42. I have the feeling that you're struggling with an XY problem, what are you really trying to accomplish? wouldn't it be a better idea to use a list of functions instead of a list of symbols representing function names? I mean, like this:
; some functions
(define (at1 x y) (+ x y))
(define (at2 x y) (- x y))
(define (at3 x y) (* x y))
; a list of functions
(define lst (list at1 at2 at3))
; operands
(define value1 30)
(define value2 12)
; apply the first function from the list of functions
((car lst) value1 value2)
=> 42
(define [DML vara]
(cond
((atom? (car vara))
(cond
((eqan? (car vara) 'N)
(display (cdr vara)))
(else (negate vara)))
)))
I'm currently trying to save the content of a return right now for simplicity I was testing the negate function it "returns" a list and I wanted to save the result of that function to do testing. How do I actually save the list return from negate.
Kind of like (x = (negate vara)) where x is the list. I look up let on google and in stack over flow but I can't find a very simple basic assignment.
Excuse my poor syntax on scheme I'm just starting..and going from imperative language to function isn't so smooth..
edit:
I wanted to print out the result expression of (negate vara) but since scheme only prints out the last "recursive call" (pardon my bad wording). I wanted it to use the resulting list from (negate vara) but still print out that list like
say if I had
(else (test (negate vara)))
...
(define (test vara)
(display "test")
)
I wanted it to display
'(O a b)) ;list
here
As you already know, a let expression will do the trick:
(let ((x 10)
(y 20))
(+ x y))
=> 30
The above expression binds values to two variables, x and y. These bindings will exist inside the body of the let. Implicitly, all the expressions in the let form are packed inside a begin, and the end result of the whole expression is the final expression. Notice that one binding cannot refer to the others in the definition part; if one variable needs to refer to previous definitions, then use a let*:
(let* ((x 10)
(y (* x 2)))
(+ x y))
=> 30
Finally, if you need to create a recursive definition use letrec:
(letrec ((fact (lambda (x)
(if (zero? x) 1 (* x (fact (sub1 x)))))))
(fact 10))
=> 3628800
You could make a procedure like you proposed:
(define (test var)
(display var)
var)
(test (negate (test vara)))) ; prints our argument and return
Or you could use DrRacket and use the debugger. You'll miss it after using it once!
Two related questions in one:
Can Clojure's core.logic module perform arithmetic, logical comparison, etc, like ordinary Prolog? I am envisioning something like the following:
(defrel points person n)
(fact :bob 2)
(fact :charlie 3)
(run* [q] (fresh [x y]
(points :bob x)
(points :charlie y)
(< x y)
(== q (+ x y))))
=> (5)
In this example, neither the logical comparison (< x y) nor the attempted binding of q to (+ x y) works. I suppose that this is because I'm working with LVars, not integers at this point, and I can't make these comparisons because the symbols aren't yet bound. But it works in prolog:
points(bob, 2).
points(charlie, 3).
?- points(bob, X), points(charlie, Y), Result is X + Y.
=> Result = 5.
In a similar vein, can I somehow use Clojure functions (which return booleans or other "truthy" values) as logic predicates? In other words, to use functions to tell Minikanren which terms unify or not. Something along the lines of:
(defmagic startswithhi-o [v]
(.startsWith v "hi"))
(defrel person n)
(fact person "bob")
(fact person "hillary")
(run* [q]
(fresh [n]
(person n)
(startswithhi-o n)
(== q n)))
=> ("hillary")
If I try things like this I get errors also complaining that the LVars aren't bound. Is there a way to do this?
Lastly if anyone has read this far, I might as well ask: are there plans to incorporate probabilistic logic into core.logic, along the lines of:
http://dtai.cs.kuleuven.be/problog/ ?
I'm not holding my breath but it would be awesome!
Non-relational arithmetic is possible via project.
(run 1 [q]
(fresh [x y]
(== x 1)
(== y 2)
(project [x y]
(== q (+ x y)))))
(3)
I believe the Prolog example given is also non-relational.
The second half of your question can also be solved via project, but you must be careful that you always input a ground value.
(defn startwith [x]
(project [x]
(== true (.startsWith x "hi"))))
PS: Hold your breath for Constraint Logic Programming to come to core.logic!
I believe you have to "project" (nonrel/project) a logic variable to its binding before you can apply a function to it:
(defrel points person n)
(fact points :bob 2)
(fact points :charlie 3)
(run* [q]
(exist [x y]
(points :bob x)
(points :charlie y)
(project [x y]
(== true (< x y))
(== q (+ x y)))))
Note that exist substitutes for fresh in the original snippet and the additional argument for the fact declarations.
Say I have this list
'((c d) (4 6) (m n) (z z))
How can I group the first and last element of each inner list and append it at the end so that my output would be something like this:
(c 4 m z z n 6 d)
Any help will be greatly appreciated!
Here is one way in Clojure (which is a lisp dialect):
user=> (def l '((c d) (4 6) (m n) (z z)) )
user=> (concat (map first l) (reverse (map second l)))
(c 4 m z z n 6 d)
Really depends on your problem as to what implementation suits best.
You need to build your list from two ends. I would suggest the following:
Create two lists out of the existing one
Put the two new lists together when the input list is empty, reversing the second list before putting them together.
So you should expect the function call to look like:
(myFunc inputList forwardList willBeBackwardList)
and when inputList is empty you want to do something like
(append forwardList (reverse willBeBackwardList))
(exact built-in function names will vary by the lisp you're using).