Why isn't there a BOOLEANP predicate? - lisp

To check for a symbol, one might use symbolp. To check for a number, one might use numberp. And so on…
Why is there no booleanp to check for a boolean value? Of course I can use
(defun booleanp (x)
(or (null x)
(equal x t)))
but is there an easier (built-in) way of doing this? If not, is there a special reason, why just this predicate is missing?

I don't know the exact history of numberp, symbolp, the boolean type, and other type predicates, but with the availability of the generic type predicate typep it is not necessary to have a separate predicate for every type. A short way to see if something is of type boolean is (typep object 'boolean).

I'd dare to guess that the real reason for this is that even though only NIL and T are (TYPEP 'BOOLEAN), any value is a valid boolean expression. I.e. any value except for NIL is considered true in an IF form. Thus, the usefulness of a BOOLEANP would be limited, if not harmful as it would return false for things that are perfectly valid input to the conditional forms.

Related

how can I compare syntax objects in racket?

I'd like to compare the code contents of two syntax objects and ignore things like contexts. Is converting them to datum the only way to do so? Like:
(equal? (syntax->datum #'(x+1)) (syntax->datum #'(x+1)))
If you want to compare both objects without deconstructing them at all, then yes.
HOWEVER, the problem with this method is that it only compares the datum attached to two syntax objects, and won't actually compare their binding information.
The analogy that I've heard (from Ryan Culpepper), is this is kind of like taking two paintings, draining of them of their color, and seeing if they are identical. While they might be similar in some ways, you will miss a lot of differences from the different colors.
A better approach (although it does require some work), is to use syntax-e to destruct the syntax object into more primitive lists of syntax objects, and do this until you get identifiers (basically a syntax object whose datum is a symbol), from there, you can generally use free-identifier=? (and sometimes bound-identifier=? to see if each identifier can bind each other, and identifier-binding to compare module level identifiers.
The reason why there isn't a single simple predicate to compare two arbitrary syntax objects is because, generally, there isn't really one good definition for what makes two pieces of code equal, even if you only care about syntactic equality. For example, using the functions referenced above doesn't track internal bindings in a syntax object, so you will still get a very strict definition of what it means to be 'equal'. that is, both syntax objects have the same structure with identifiers that are either bound to the same module, or are free-identifier=?.
As such, before you use this answer, I highly recommend you take a step back and make sure this is really what you want to do. Once in a blue moon it is, but most of the time you actually are trying to solve a similar, yet simpler, problem.
Here's a concrete example of one possible way you could do the "better approach" Leif Andersen mentioned.
I have used this in multiple places for testing purposes, though if anyone wanted to use it in non-test code, they would probably want to re-visit some of the design decisions.
However, things like the equal?/recur pattern used here should be helpful no matter how you decide to define what equality means.
Some of the decisions you might want to make different choices on:
On identifiers, do you want to check that the scopes are exactly the same (bound-identifier=?), or would you want to assume that they would be bound outside of the syntax object and check that they are bound to the same thing, even if they have different scopes (free-identifier=?)? Note that if you choose the first one, then checking the results of macro expansion will sometimes return #false because of scope differences, but if you choose the second one, then if any identifier is not bound outside of the syntax object, then it would be as if you only care about symbol=? equality on names, so it will return #true in some places where it shouldn't. I chose the first one bound-identifier=? here because for testing, a "false positive" where the test fails is better than a "false negative" where the tests succeeds in cases it shouldn't.
On source locations, do you want to check that they are equal, or do you want to ignore them? This code ignores them because it's only for testing purposes, but if you want equality only for things which have the same source location, you might want to check that using functions like build-source-location-list.
On syntax properties, do you want to check that they are equal, or do you want to ignore them? This code ignores them because it's only for testing purposes, but if you want to check that you might want to use functions like syntax-property-symbol-keys.
Finally here is the code. It may not be exactly what you want depending on how you answered the questions above. However, its structure and how it uses equal?/recur might be helpful to you.
(require rackunit)
;; Works on fully wrapped, non-wrapped, and partially
;; wrapped values, and it checks that the inputs
;; are wrapped in all the same places. It checks scopes,
;; but it does not check source location.
(define-binary-check (check-stx=? stx=? actual expected))
;; Stx Stx -> Bool
(define (stx=? a b)
(cond
[(and (identifier? a) (identifier? b))
(bound-identifier=? a b)]
[(and (syntax? a) (syntax? b))
(and (bound-identifier=? (datum->syntax a '||) (datum->syntax b '||))
(stx=? (syntax-e a) (syntax-e b)))]
[else
(equal?/recur a b stx=?)]))

What's the return value of `define` in Scheme?

I'm curious about the return value of define in Scheme. So I wrote the following lines in Racket
#lang r5rs
(display (define a 3))
And get the error
define: not allowed in an expression context in: (define a 3)
I have 2 questions about this:
Does it mean that define has no return value?
According to R5RS, define is not an expression. It's a program structure. Is it true that only expressions have return values, and other forms don't?
"If a tree falls in a forest and no one is around to hear it, does it make a sound?"
It's not valid to use define in any context where a return value could meaningfully be obtained. So it's moot whether it has a return value or not; you'll never be able to observe it.
In Scheme, define can only be used in two places:
At the top level, or
At the very beginning of a "body".
In neither of those places is a "return value" relevant.

Is an empty list in Lisp built from a cons cell?

I'm trying to emulate Lisp-like list in JavaScript (just an exercise with no practical reason), but I'm struggling to figure out how to best represent an empty list.
Is an empty list just a nil value or is it under the hood stored in a cons cell?
I can:
(car '())
NIL
(cdr '())
NIL
but an empty list for sure can not be (cons nil nil), because it would be indistinguishable from a list storing a single nil. It would need to store some other special value.
On the other hand, if an empty list is not built from a cons cell, it seems impossible to have a consistent high-level interface for appending a single value to an existing list. A function like:
(defun append-value (list value) ...
Would modify its argument, but only if it is not an empty list, which seems ugly.
Believe it or not, this is actually a religious question.
There are dialects that people dare to refer to as some kind of Lisp in which empty lists are conses or aggregate objects of some kind, rather than just an atom like nil.
For example, in "MatzLisp" (better known as Ruby) lists are actually arrays.
In NewLisp, lists are containers: objects of list type which contain a linked list of the items, so empty lists are empty containers. [Reference].
In Lisp languages that aren't spectacular cluster-fumbles of this sort, empty lists are atoms, and non-empty lists are binary cells with a field which holds the first item, and another field that holds the rest of the list. Lists can share suffixes. Given a list like (1 2 3) we can use cons to create (a 1 2 3) and (b c 1 2 3) both of which share the storage for (1 2 3).
(In ANSI Common Lisp, the empty list atom () is the same object as the symbol nil, which evaluates to itself and also serves as Boolean false. In Scheme, () isn't a symbol, and is distinct from the Boolean false #f object. However Scheme lists are still made up of pairs, and terminated by an atom.)
The ability to evaluate (car nil) does not automatically follow from the cons-and-nil representation of lists, and if we look at ancient Lisp documentation, such as the Lisp 1.5 manual from early 1960-something, we will find that this was absent. Initially, car was strictly a way to access a field of the cons cell, and required strictly a cons cell argument.
Good ideas like allowing (car nil) to Just Work (so that hackers could trim many useless lines of code from their programs) didn't appear overnight. The idea of allowing (car nil) may have appeared from InterLisp. In any case, Evolution Of Lisp paper claims that MacLisp (one of the important predecessors of Common Lisp, unrelated to the Apple Macintosh which came twenty years later), imitated this feature from InterLisp (another one of the significant predecessors).
Little details like this make the difference between pleasant programming and swearing at the monitor: see for instance A Short Ballad Dedicated to the Growth of Programs inspired by one Lisp programmer's struggle with a bletcherous dialect in which empty lists cannot be accessed with car, and do not serve as a boolean false.
An empty list is simply the nil symbol (and symbols, by definition, are not conses). car and cdr are defined to return nil if given nil.
As for list-mutation functions, they return a value that you are supposed to reassign to your variable. For example, look at the specification for the nreverse function: it may modify the given list, or not, and you are supposed to use the return value, and not rely on it to be modified in-place.
Even nconc, the quintessential destructive-append function, works that way: its return value is the appended list that you're supposed to use. It is specified to modify the given lists (except the last one) in-place, but if you give it nil as the first argument, it can't very well modify that, so you still have to use the return value.
NIL is somewhat a strange beast in Common Lisp because
it's a symbol (meaning that symbolp returns T)
is a list
is NOT a cons cell (consp returns NIL)
you can take CAR and CDR of it anyway
Note that the reasons behind this are probably also historical and you shouldn't think that this is the only reasonable solution. Other Lisp dialects made different choices.
Try it with your Lisp interpreter:
(eq nil '())
=> t
Several operations are special-cased to do unorthogonal (or even curious :-) things when operating on nil / an empty list. The behavior of car and cdr you were investigating is one of those things.
The idenity of nil as the empty list is one of the first things you learn about Lisp. I tried to come up with a good Google hit but I'll just pick one because there are so many: http://www.cs.sfu.ca/CourseCentral/310/pwfong/Lisp/1/tutorial1.html

In Lisp, how do you get the value of an expression?

This will print data, but I want it to print show. I want to print the value, not the expression, how would I do it?
(defun display (x)
(list x))
(setq temp 'data)
(set temp 'show)
(display 'data)
what if u dont know if the variable is bound or not? i have to write a function that take a key and a value, if key does not exist, then i have to do setq key value, if the key already exist, then i would add the value to the key. In this case, if i do (storedata key value), if value have not been bounded, i get an unbound error, how would i handle this case?
for example, if there is no mydata and i do (storedata value mydata) then mydata would become (value), now if i do (storedata value2 mydata) then mydata becomes (value value2).
Quoting a list or a symbol in Lisp with ' is exactly equivalent to using the special form (quote ...). It's specifically for making the quoted thing not get evaluated. 'data in Lisp code or typed into the REPL is the same thing as (quote data), and evaluates to the symbol data.
data without the quote evaluates to the value of the variable data in the current scope. So, at the REPL:
[1]> (setq data 14)
14
[2]> data
14
The first expression also evaluates to 14 because setq returns the value of the bound variable (in this respect acting like the assignment operator = in C).
What you've done in the above code is to set the variable named temp to contain the symbol data, then, by using set (without the setq), set the variable named data to the symbol show. This is a bit similar to using soft references in Perl (for example), but I don't think it's particularly widely used or advisable as a Lisp technique.
By the way, your display procedure is probably not doing what you think either: it returns a single element list of whatever you pass to it. The fact that the value gets printed when you type it into the REPL is just because the value of any expression gets printed at the REPL. To display a value in a program you might use print or maybe format. (I'm assuming you're using Common Lisp, since it's obviously not Scheme, but maybe it's some other Lisp variety, in which case that link won't help.)
You are quoting data. If you want it to be evaluated you should just call
(display data)

Apply-recur macro in Clojure

I'm not very familiar with Clojure/Lisp macros. I would like to write apply-recur macro which would have same meaning as (apply recur ...)
I guess there is no real need for such macro but I think it's a good exercise. So I'm asking for your solution.
Well, there really is no need for that, if only because recur cannot take varargs (a recur to the top of the function takes a single final seqable argument grouping all arguments pass the last required argument). This doesn't affect the validity of the exercise, of course.
However, there is a problem in that a "proper" apply-recur should presumably handle argument seqs returned by arbitrary expressions and not only literals:
;; this should work...
(apply-recur [1 2 3])
;; ...and this should have the same effect...
(apply-recur (vector 1 2 3))
;; ...as should this, if (foo) returns [1 2 3]
(apply-recur (foo))
However, the value of an arbitrary expression such as (foo) is simply not available, in general, at macro expansion time. (Perhaps (vector 1 2 3) might be assumed to always yield the same value, but foo might mean different things at different times (one reason eval wouldn't work), be a let-bound local rather than a Var (another reason eval wouldn't work) etc.)
Thus to write a fully general apply-recur, we would need to be able to determine how many arguments a regular recur form would expect and have (apply-recur some-expression) expand to something like
(let [seval# some-expression]
(recur (nth seval# 0)
(nth seval# 1)
...
(nth seval# n-1))) ; n-1 being the number of the final parameter
(The final nth might need to be nthnext if we're dealing with varargs, which presents a problem similar to what is described in the next paragraph. Also, it would be a good idea to add an assertion to check the length of the seqable returned by some-expression.)
I am not aware of any method to determine the proper arity of a recur at a particular spot in the code at macro-expansion time. That does not mean one isn't available -- that's something the compiler needs to know anyway, so perhaps there is a way to extract that information from its internals. Even so, any method for doing that would almost certainly need to rely on implementation details which might change in the future.
Thus the conclusion is this: even if it is at all possible to write such a macro (which might not even be the case), it is likely that any implementation would be very fragile.
As a final remark, writing an apply-recur which would only be capable of dealing with literals (actually the general structure of the arg seq would need to be given as a literal; the arguments themselves -- not necessarily, so this could work: (apply-recur [foo bar baz]) => (recur foo bar baz)) would be fairly simple. I'm not spoiling the exercise by giving away the solution, but, as a hint, consider using ~#.
apply is a function that takes another function as an argument. recur is a special form, not a function, so it cannot be passed to apply.