How to convert string to list in Common Lisp - lisp

Just like
The String is
> "((1 0)(0 1))"
required
>((1 0)(0 1))
I am also using intern function but it returns in form of ((1\ 0)(0\ 1))

You can use read-from-string:
(read-from-string "((1 0)(0 1))")
This function has many parameters and returns two values: the first is what you need, the list:
CL-USER> (car (read-from-string "((1 0)(0 1))"))
(1 0)
You can read about this function in the official documentation.

Related

What is wrong with my lisp function?

I am writing a function called palindrome that tests if a list is a palindrome. It works 100% for regular lists such as (1 2 1), but if I use (1 (2) 1), I get a bad argument type error.
Here is my function
(defun palindrome (x)
(if (NULL x) t
(let ( ( a (car x)) (b (lastelement x)))
(if ( = a b)
(palindrome (cdr (butlast x)))
nil))))
The function = is reserved exclusively for numbers. When used with a list or other type of element it returns an error. Use instead eql.
Incidentally, note that your function is very inefficient. Normally (i.e. not for homework) you would create a reversed copy of the list and compare it element by element with the original list.

Lisp quote work internally

How does lisp quote work internally?
For example:
(quote (+ 1 (* 1 2)) )
seems to be equivalent to
(list '+ 1 (list '* 1 2))
which means it is some how symbolizing the Head values recursively. Is this function a built in?
Run (equal (quote (+ 1 (* 1 2))) (list '+ 1 (list '* 1 2))) if you don't believe me.
How does it work?
quote is really really simple to implement. It does mostly nothing. The quote special operator just returns the enclosed object like it is. Nothing more. No evaluation. The object is not changed in any way.
Evaluation of quoted forms
Probably a good time to read McCarthy, from 1960:
Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I
Pages 16/17 explain evaluation with eval. Here:
eq [car [e]; QUOTE] → cadr [e];
or in s-expression notation:
(cond
...
((eq (car e) 'quote)
(cadr e))
...)
Above code implements the evaluation rule for QUOTE: If the expression is a list and the first element of the list is the symbol QUOTE, then return the second element of the list.
Equivalence of a quoted list with a list created by LIST
(equal (quote (+ 1 (* 1 2)))
(list '+ 1 (list '* 1 2)))
The result is T. This means that both result lists are structurally equivalent.
(eq (quote (+ 1 (* 1 2)))
(list '+ 1 (list '* 1 2)))
The result is NIL. This means that the first cons cell of the linked lists are not the same objects. EQ tests whether we really have the same cons cell object.
QUOTE returns a literal data object. The consequences of modifying this object is undefined. So, don't do it.
LIST returns a new freshly consed list each time it is called. The fresh new list will not share any cons cells with any earlier allocated list.
So the main difference is that QUOTE is a built-in operator, which returns literal and unevaluated data. Whereas LIST is a function which creates a new,fresh list with its arguments as contents.
See the effects with respect to EQ and EQUAL:
CL-USER 6 >
(flet ((foo () (quote (+ 1 (* 1 2))))
(bar () (list '+ 1 (list '* 1 2))))
(list (list :eq-foo-foo (eq (foo) (foo)))
(list :eq-foo-bar (eq (foo) (bar)))
(list :eq-bar-bar (eq (foo) (bar)))
(list :equal-foo-foo (equal (foo) (foo)))
(list :equal-foo-bar (equal (foo) (bar)))
(list :equal-bar-bar (equal (foo) (bar)))))
((:EQ-FOO-FOO T)
(:EQ-FOO-BAR NIL)
(:EQ-BAR-BAR NIL)
(:EQUAL-FOO-FOO T)
(:EQUAL-FOO-BAR T)
(:EQUAL-BAR-BAR T))
is quote a function?
quote can't be a function, since it returns its enclosed data unevaluated. Thus it is a special evaluation rule.
If quote were a function, it's arguments were evaluated. But that's exactly what is NOT what quote is supposed to do.
why does Lisp need QUOTE?
Lisp usually uses s-expressions to write Lisp code. So s-expressions have a both purpose to denote data and we use it to write programs. In a Lisp program lists are used for function calls, macro forms and special forms. symbols are used as variables:
(+ n 42)
Here (+ n 42) is a list and n is a symbol. But we also want to use lists as data in our programs and we want to use symbols as data. Thus we have to quote them, so that Lisp will not see them as programs, but as data:
(append '(+ n) '(42)) evaluates to (+ n 42)
Thus in a Lisp program, lists and variables are by default part of the language elements, for example as function calls and variables. If we want to use lists and symbols as literal data, we have to quote them, to prevent the evaluator treating them as Lisp code to evaluate.
quote does nothing more than return its argument unevaluated. But what is an unevaluated argument?
When a Lisp program is defined, it is either read from textual source into s-expression form or constructed directly in terms of s-expressions. A macro would be an example of generating s-expressions. Either way there is a data structure comprising (mostly) symbols and conses that represents the program.
Most Lisp expressions will call upon evaluation and compilation machinery to interpret this data structure as terms in a program. quote is treated specially and passed these uninterpreted symbols and conses as its argument. In short, quote does almost nothing - the value it returns already exists and is simply passed through.
You can observe the difference between passing through and fresh construction by using eq to test the identity of the return value of quote:
(defun f () '(1 2))
(defun g () (list 1 2))
(eq (f) (f)) => T
(eq (g) (g)) => NIL
As you can see, quote returns the same conses each time through.

How to use `apply-partially`?

I'm trying to use apply-partially in a local context:
((apply-partially '+ 1) `(1))
This give me the following error: eval: Invalid function: (apply-partially (quote +) 1)
similarly:
(let ((addone (apply-partially #'+ 1)))
(addone 2))
Why any of this example doesn't work?
That's because Emacs Lisp has separate namespaces for variables and functions. A function that has been defined using defun can be called by putting its name first in a list and evaluating that, but if you have a function as a value (as returned by apply-partially) you need to use funcall or apply.
The difference between funcall and apply is that funcall just calls the function with the arguments given, while apply treats its last argument as a list that should be appended to the argument list. Thus, your first example needs to be written with apply, since + doesn't work with lists:
(apply (apply-partially '+ 1) `(1))
For your second example, use funcall, since the function argument is not wrapped in a list:
(let ((addone (apply-partially #'+ 1)))
(funcall addone 2))

Differences between equal strings

I am trying to write a simple parser in Racket, using the parser-tools. I got a behaviour which I could not explain (I am a Racket newbie, perhaps that is trivial).
Consider the following code:
#lang racket
(require parser-tools/yacc
parser-tools/lex
(prefix-in : parser-tools/lex-sre))
(define-tokens value-tokens ;;token which have a value
(STRING-VALUE ))
(define-empty-tokens op-tokens ;;token without a values
(EOF))
(define-lex-abbrevs ;;abbreviation
[STRING (:+ (:or (:/ "a" "z") (:/ "A" "Z") (:/ "0" "9") "." "_" "-"))]
)
(define lex-token
(lexer
[(eof) 'EOF]
;; recursively call the lexer on the remaining input after a tab or space. Returning the "1+1")
;; result of that operation. This effectively skips all whitespace.
[(:or #\tab #\space #\newline)
(lex-token input-port)]
[(:seq STRING) (token-STRING-VALUE lexeme)]
))
(define test-parser
(parser
(start query)
(end EOF)
(tokens value-tokens op-tokens)
(error (λ(ok? name value) (printf "Couldn't parse: ~a\n" name)))
(grammar
(query [(STRING-VALUE) $1])
)))
(define s (open-input-string
"abcd123"))
(define res
(test-parser (lambda () (lex-token s))))
(define str "abcd123")
After those definitions, res is a string:
> (string? res)
#t
and so is str.
If I try to execute a comparison with the "abcd123" string I get two different results:
> (eq? res "abcd123")
#f
> (eq? str "abcd123")
#t
Why is that? What am I missing here?
You should compare strings with equal?.
Like many programming languages there is a difference between same object and two objects that look the same. You probably should have a look at the Question about the difference between eq?, eqv?, equal? and =
Racket has string=? which compares strings specifically and might be faster than the less specific equal?.

How do I convert a string to a symbol for use as a key in the Lisp "assoc" function?

I have this association-list in Common Lisp:
(defvar base-list (list (cons 'a 0) (cons 2 'c)))
I have to call assoc when my argument is of type string.
For the pair (A . 0) I have to convert "a" to a symbol, and for the pair (2 . C) I have to convert "2" to a symbol. How can I do that?
This should work like this:
CL-USER 28 : 1 > (assoc (convert-string-to-symbol "a") base-list)
(A . 0)
CL-USER 28 : 1 > (assoc (convert-number-to-symbol "2") base-list)
(2 . C)
I tried using intern but got NIL:
CL-USER 29 : 1 > (assoc (intern "a") base-list)
NIL
The function you want is called read-from-string:
CL-USER> (read-from-string "a")
A
1
CL-USER> (read-from-string "2")
2
1
CL-USER>
Note that solutions based on using intern or find-symbol would not work for strings representing numbers (e.g., "2") on most implementations.
You were close with intern; you just had the case wrong. Try this:
> (assoc (intern "A") base-list)
(A . 0)
Note that here the name-as-string is capitalized.
Alternately, you could use find-symbol to look for an existing symbol by name:
> (assoc (find-symbol "A") base-list)
(A . 0)
The key here is that when you wrote your original defvar form, the reader read the string "a" and—by virtue of the current readtable case—converted the symbol name to be uppercase. Symbols with names of different case are not equal. It just so happens that at read time the reader is projecting what you wrote (lowercase) to something else (uppercase).
You can inspect the current case conversion policy for the current reader using the readtable-case function:
> (readtable-case *readtable*)
:UPCASE
To learn more about how the readtable case and the reader interact, see the discussion in section 23.1.2 of the Hyperspec.