String Comparison in Common Lisp - functional-programming

I am new to Common Lisp and Functional programming in general. I have a function lets call it "wordToNumber", I want it to check if the input string is "one" "two" "three".. etc (0-9) only. and I want to return 1 2 3 etc. so (wordToNumber "one") should output the number 1. I'm having some trouble with string comparison, tried using eq and eql, but its not working, from what I read it is comparing memory location not actual string. Is there an easier way to go about this or is there someway to compare strings. I need any examples to be purely functional programming, no loops and stuff. This is a small portion of a project I'm working on for school.
Oh, for string comparison im just using a simple function at the moment like this:
(defun wordToNumber(x)
(if(eq 'x "one")(return-from wordToNumber 1)))
and calling it with this : (wordToNumber "one")
keep getting Nil returned
Thanks for any help

The functions to compare strings are string= and string-equal, depending on whether you want the comparison to be case-sensitive.
And when you want to compare the value of a variable, you mustn't quote it, since the purpose of quoting is to prevent evaluation.
(defun word-to-number (x)
(cond ((string-equal x "one") 1)
((string-equal x "two") 2)
((string-equal x "three") 3)
...
))

As a practical matter, before you make a ten-branch conditional, consider this: you can pass string= and string-equal (and any other binary function) as an :test argument to most of the sequence functions. Look though the sequence functions and see if there's something that seems relevant to this problem. http://l1sp.org/cl/17.3 (There totally is!)

One nice thing about Lisp is the apropos function. Lisp is a big language and usually has what you want, and (apropos "string") would prolly have worked for you. I recommend also the Lisp Hyperpec: http://www.lispworks.com/documentation/HyperSpec/Front/
eq is good for symbols, CLOS objects, and even cons cells but be careful: (eq (list 1) (list 1)) is false because each list form returns a different cons pointing to the same number.
eql is fine for numbers and characters and anything eq can handle. One nice thing is that (eql x 42) works even if x is not a number, in which case (= x 42) would not go well.
You need equal for lists and arrays, and strings are arrays so you could use that. Then there is equalp, which I will leave as an exercise.

Related

Why is foldl defined in a strange way in Racket?

In Haskell, like in many other functional languages, the function foldl is defined such that, for example, foldl (-) 0 [1,2,3,4] = -10.
This is OK, because foldl (-) 0 [1, 2,3,4] is, by definition, ((((0 - 1) - 2) - 3) - 4).
But, in Racket, (foldl - 0 '(1 2 3 4)) is 2, because Racket "intelligently" calculates like this: (4 - (3 - (2 - (1 - 0)))), which indeed is 2.
Of course, if we define auxiliary function flip, like this:
(define (flip bin-fn)
(lambda (x y)
(bin-fn y x)))
then we could in Racket achieve the same behavior as in Haskell: instead of (foldl - 0 '(1 2 3 4)) we can write: (foldl (flip -) 0 '(1 2 3 4))
The question is: Why is foldl in racket defined in such an odd (nonstandard and nonintuitive) way, differently than in any other language?
The Haskell definition is not uniform. In Racket, the function to both folds have the same order of inputs, and therefore you can just replace foldl by foldr and get the same result. If you do that with the Haskell version you'd get a different result (usually) — and you can see this in the different types of the two.
(In fact, I think that in order to do a proper comparison you should avoid these toy numeric examples where both of the type variables are integers.)
This has the nice byproduct where you're encouraged to choose either foldl or foldr according to their semantic differences. My guess is that with Haskell's order you're likely to choose according to the operation. You have a good example for this: you've used foldl because you want to subtract each number — and that's such an "obvious" choice that it's easy to overlook the fact that foldl is usually a bad choice in a lazy language.
Another difference is that the Haskell version is more limited than the Racket version in the usual way: it operates on exactly one input list, whereas Racket can accept any number of lists. This makes it more important to have a uniform argument order for the input function).
Finally, it is wrong to assume that Racket diverged from "many other functional languages", since folding is far from a new trick, and Racket has roots that are far older than Haskell (or these other languages). The question could therefore go the other way: why is Haskell's foldl defined in a strange way? (And no, (-) is not a good excuse.)
Historical update:
Since this seems to bother people again and again, I did a little bit of legwork. This is not definitive in any way, just my second-hand guessing. Feel free to edit this if you know more, or even better, email the relevant people and ask. Specifically, I don't know the dates where these decisions were made, so the following list is in rough order.
First there was Lisp, and no mention of "fold"ing of any kind. Instead, Lisp has reduce which is very non-uniform, especially if you consider its type. For example, :from-end is a keyword argument that determines whether it's a left or a right scan and it uses different accumulator functions which means that the accumulator type depends on that keyword. This is in addition to other hacks: usually the first value is taken from the list (unless you specify an :initial-value). Finally, if you don't specify an :initial-value, and the list is empty, it will actually apply the function on zero arguments to get a result.
All of this means that reduce is usually used for what its name suggests: reducing a list of values into a single value, where the two types are usually the same. The conclusion here is that it's serving a kind of a similar purpose to folding, but it's not nearly as useful as the generic list iteration construct that you get with folding. I'm guessing that this means that there's no strong relation between reduce and the later fold operations.
The first relevant language that follows Lisp and has a proper fold is ML. The choice that was made there, as noted in newacct's answer below, was to go with the uniform types version (ie, what Racket uses).
The next reference is Bird & Wadler's ItFP (1988), which uses different types (as in Haskell). However, they note in the appendix that Miranda has the same type (as in Racket).
Miranda later on switched the argument order (ie, moved from the Racket order to the Haskell one). Specifically, that text says:
WARNING - this definition of foldl differs from that in older versions of Miranda. The one here is the same as that in Bird and Wadler (1988). The old definition had the two args of `op' reversed.
Haskell took a lot of stuff from Miranda, including the different types. (But of course I don't know the dates so maybe the Miranda change was due to Haskell.) In any case, it's clear at this point that there was no consensus, hence the reversed question above holds.
OCaml went with the Haskell direction and uses different types
I'm guessing that "How to Design Programs" (aka HtDP) was written at roughly the same period, and they chose the same type. There is, however, no motivation or explanation — and in fact, after that exercise it's simply mentioned as one of the built-in functions.
Racket's implementation of the fold operations was, of course, the "built-ins" that are mentioned here.
Then came SRFI-1, and the choice was to use the same-type version (as Racket). This decision was question by John David Stone, who points at a comment in the SRFI that says
Note: MIT Scheme and Haskell flip F's arg order for their reduce and fold functions.
Olin later addressed this: all he said was:
Good point, but I want consistency between the two functions.
state-value first: srfi-1, SML
state-value last: Haskell
Note in particular his use of state-value, which suggests a view where consistent types are a possibly more important point than operator order.
"differently than in any other language"
As a counter-example, Standard ML (ML is a very old and influential functional language)'s foldl also works this way: http://www.standardml.org/Basis/list.html#SIG:LIST.foldl:VAL
Racket's foldl and foldr (and also SRFI-1's fold and fold-right) have the property that
(foldr cons null lst) = lst
(foldl cons null lst) = (reverse lst)
I speculate the argument order was chosen for that reason.
From the Racket documentation, the description of foldl:
(foldl proc init lst ...+) → any/c
Two points of interest for your question are mentioned:
the input lsts are traversed from left to right
And
foldl processes the lsts in constant space
I'm gonna speculate on how the implementation for that might look like, with a single list for simplicity's sake:
(define (my-foldl proc init lst)
(define (iter lst acc)
(if (null? lst)
acc
(iter (cdr lst) (proc (car lst) acc))))
(iter lst init))
As you can see, the requirements of left-to-right traversal and constant space are met (notice the tail recursion in iter), but the order of the arguments for proc was never specified in the description. Hence, the result of calling the above code would be:
(my-foldl - 0 '(1 2 3 4))
> 2
If we had specified the order of the arguments for proc in this way:
(proc acc (car lst))
Then the result would be:
(my-foldl - 0 '(1 2 3 4))
> -10
My point is, the documentation for foldl doesn't make any assumptions on the evaluation order of the arguments for proc, it only has to guarantee that constant space is used and that the elements in the list are evaluated from left to right.
As a side note, you can get the desired evaluation order for your expression by simply writing this:
(- 0 1 2 3 4)
> -10

Remove duplicate strings from a list

I have a dead simple Common Lisp question: what is the idiomatic way of removing duplicates from a list of strings?
remove-duplicates works as I'd expect for numbers, but not for strings:
* (remove-duplicates '(1 2 2 3))
(1 2 3)
* (remove-duplicates '("one" "two" "two" "three"))
("one" "two" "two" "three")
I'm guessing there's some sense in which the strings aren't equal, most likely because although "foo" and "foo" are apparently identical, they're actually pointers to different structures in memory. I think my expectation here may just be a C hangover.
You have to tell remove-duplicates how it should compare the values. By default, it uses eql, which is not sufficient for strings. Pass the :test function as in:
(remove-duplicates your-sequence :test #'equal).
(Edit to address the question from the comments): As an alternative to equal, you could use string= in this example. This predicate is (in a way) less generic than equal and it might (could, probably, possibly, eventually...) thus be faster. A real benefit might be, that string= can tell you, if you pass a wrong value:
(equal 1 "foo")
happily yields nil, whereas
(string= 1 "foo")
gives a type-error condition. Note, though, that
(string= "FOO" :FOO)
is perfectly well defined (string= and its friend are defined in terms of "string designators" not strings), so type safety would go only so far here.
The standard eql predicate, on the other hand, is almost never the right way to compare strings. If you are familiar with the Java language, think of eql as using == while equal (or string=, etc.) calling the equals(Object) method. Though eql does some type introspection (as opposed to eq, which does not), for most (non-numeric) lisp types, eql boils down to something like a pointer comparison, which is not sufficient, if you want to discriminate values based on what they actually contain, and not merely on where in memory they are located.
For the more Pythonic inclined, eq (and eql for non-numeric types) is more like the is operator, whereas equal is more like == which calls __eq__.

Got some problems with CLISP's nested list and lambda expression

Nested lists in Common Lisp really confused me. Here is the problem:
By using recursion, let (nested-list 'b '(a (b c) d)) return t
if the first argument appears in the second argument (which could be
a nested list), and nil otherwise.
I tried find, but it only works if the first argument is '(b c).
I turned my eyes on lambda expressions. I want to flatten the second
argument first, and then use eq to compare the arguments.
(defun nested-list (x y)
(cond
((null y) ())
(t (append (lambda (flatten) (first y))
Then I got stuck. Even though I read a lot of stuff about lambda
expessions, it still confused me. I do not know how to recall it when
I need, I knew the funcall function, but you know I just cannot get
it. I just learnt Common Lisp for 5 days, so I hope you can give me a
hint. Thanks a lot!
First of all unless you mistyped if instead of iff the problem is quite trivial, just return t and you're done :-)
Seriously speaking instead when you need to solve a problem using recursion the idea often is simply:
if we're in a trivial case just return the answer
otherwise the answer is the same answer we'd get by solving a problem that it's just a little bit simpler that this, and we call ourself to solve this simplified version.
In the specific consider:
If the second argument is an empty list the answer is NIL
If the first argument is equal to the first element of the second argument then just return T instead
Otherwise if the first element of the second list is a list (therefore also possibly a nested list) and the element is contained in this multilist then return true (to check this case the function is calling itself)
Otherwise just check the same problem, but first dropping the first element of the second argument, because it has been checked (this also calls recursively the same function)
So basically 1 and 2 are the trivial cases; 3 and 4 are the cases in which you solve a simpler version of the problem.

Mapping over sequence with a constant

If I need to provide a constant value to a function which I am mapping to the items of a sequence, is there a better way than what I'm doing at present:
(map my-function my-sequence (cycle [my-constant-value]))
where my-constant-value is a constant in the sense that it's going to be the same for the mappings over my-sequence, although it may be itself a result of some function further out. I get the feeling that later I'll look at what I'm asking here and think it's a silly question because if I structured my code differently it wouldn't be a problem, but well there it is!
In your case I would use an anonymous function:
(map #(my-function % my-constant-value) my-sequence)
Using a partially applied function is another option, but it doesn't make much sense in this particular scenario:
(map (partial my-function my-constant-value) my-sequence)
You would (maybe?) need to redefine my-function to take the constant value as the first argument, and you don't have any need to accept a variable number of arguments so using partial doesn't buy you anything.
I'd tend to use partial or an anonymous function as dbyrne suggests, but another tool to be aware of is repeat, which returns an infinite sequence of whatever value you want:
(map + (range 4) (repeat 10))
=> (10 11 12 13)
Yet another way that I find sometimes more readable than map is the for list comprehension macro:
(for [x my-sequence]
(my-function x my-constant-value))
yep :) a little gem from the "other useful functions" section of the api constantly
(map my-function my-sequence (constantly my-constant-value))
the pattern of (map compines-data something-new a-constant) is rather common in idomatic clojure. its relativly fast also with chunked sequences and such.
EDIT: this answer is wrong, but constantly and the rest of the "other useful functions" api are so cool i would like to leave the reference here to them anyway.

What are best practices for including parameters such as an accumulator in functions?

I've been writing more Lisp code recently. In particular, recursive functions that take some data, and build a resulting data structure. Sometimes it seems I need to pass two or three pieces of information to the next invocation of the function, in addition to the user supplied data. Lets call these accumulators.
What is the best way to organize these interfaces to my code?
Currently, I do something like this:
(defun foo (user1 user2 &optional acc1 acc2 acc3)
;; do something
(foo user1 user2 (cons x acc1) (cons y acc2) (cons z acc3)))
This works as I'd like it to, but I'm concerned because I don't really need to present the &optional parameters to the programmer.
3 approaches I'm somewhat considering:
have a wrapper function that a user is encouraged to use that immediately invokes the extended definiton.
use labels internally within a function whose signature is concise.
just start using a loop and variables. However, I'd prefer not since I'd like to really wrap my head around recursion.
Thanks guys!
If you want to write idiomatic Common Lisp, I'd recommend the loop and variables for iteration. Recursion is cool, but it's only one tool of many for the Common Lisper. Besides, tail-call elimination is not guaranteed by the Common Lisp spec.
That said, I'd recommend the labels approach if you have a structure, a tree for example, that is unavoidably recursive and you can't get tail calls anyway. Optional arguments let your implementation details leak out to the caller.
Your impulse to shield implementation details from the user is a smart one, I think. I don't know common lisp, but in Scheme you do it by defining your helper function in the public function's lexical scope.
(define (fibonacci n)
(let fib-accum ((a 0)
(b 1)
(n n))
(if (< n 1)
a
(fib-accum b (+ a b) (- n 1)))))
The let expression defines a function and binds it to a name that's only visible within the let, then invokes the function.
I have used all the options you mention. All have their merits, so it boils down to personal preference.
I have arrived at using whatever I deem appropriate. If I think that leaving the &optional accumulators in the API might make sense for the user, I leave it in. For example, in a reduce-like function, the accumulator can be used by the user for providing a starting value. Otherwise, I'll often rewrite it as a loop, do, or iter (from the iterate library) form, if it makes sense to perceive it as such. Sometimes, the labels helper is also used.

Resources