13

Common LISP and Emacs LISP have the atom type predicate. Scheme and Clojure don't have it. http://hyperpolyglot.wikidot.com/lisp

Is there a design reason for this - or is it just not an essential function to include in the API?

hawkeye
  • 34,745
  • 30
  • 150
  • 304
  • Besides general curiosity, is there a reason you'd find a use for it? An object is either an atom or a compound object, and you'd usually be interested in what kind of compound object, right? – Joel J. Adamson Aug 12 '10 at 17:13
  • Some Schemes come with various little things like atom? predefined for your convenience. For example, [Petite] Chez Scheme comes with most trivial functions you'd expect to exist. – erjiang Aug 21 '10 at 20:24

7 Answers7

15

In Clojure, the atom predicate isn't so important because Clojure emphasizes various other types of (immutable) data structures rather than focusing on cons cells / lists.

It could also cause confusion. How would you expect this function to behave when given a hashmap, a set or a vector for example? Or a Java object that represents some complex mutable data structure?

Also the name "atom" is used for something completely different - it's one of Clojure's core concurrency mechanisms to manage shared, synchronous, independent state.

mikera
  • 105,238
  • 25
  • 256
  • 415
13

Clojure has the coll? (collection?) function, which is (sort of) the inverse of atom?.

Stuart Sierra
  • 10,837
  • 2
  • 29
  • 35
7

In the book The Little Schemer, atom? is defined as follows:

(define (atom? x)
  (and (not (pair? x))
       (not (null? x))))

Noting that null is not considered an atom, as other answers have suggested. In the mentioned book atom? is used heavily, in particular when writing procedures that deal with lists of lists.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • scheme is really a weird language, it has null instead of nil, and null is not an atom. scheme must be the most weird dialect of lisp apart from javascript. – Alfgaar Dec 26 '17 at 02:56
  • I think you must add '(not (procedure? x)' to this definition, unless you take a procedure is an atom. – Alfgaar Dec 26 '17 at 04:02
6

In the entire IronScheme standard libraries which implement R6RS, I never needed such a function.

In summary:

  • It is useless
  • It is easy enough to write if you need it

Which pretty much follows Scheme's minimalistic approach.

leppie
  • 115,091
  • 17
  • 196
  • 297
2

In Scheme anything that is not a pair is an atom. As Scheme already defines the predicate pair?, the atom? predicate is not needed, as it is so trivial to define:

(define (atom? s)
    (not (pair? s)))
Vijay Mathew
  • 26,737
  • 4
  • 62
  • 93
  • Scheme does not know the difference between a pair and a list? Or has it changed the concept of pair? In Lisp there is no such a thing as a pair, only atoms, cons, and lists. As long as I know a pair consists of two things alone. So you can say that a list of two elements is a pair, but not a list of three or more. But taking a list of two elements as a pair is not conceptually good. It is better to tell one from the other. – Alfgaar Dec 26 '17 at 03:25
  • @Alfgaar: That's not quite right. A list is a recursive data structure: every list is either the empty list, or a pair where the second element, the cdr, is itself a list. A list of 100 items is still a pair, comprising a chain of pairs. – Chris Vine Dec 27 '17 at 23:32
1

It's a trivial function:

(defun atom (x)
   (not (consp x)))

It is used in list processing, when the Lisp dialect uses conses to build lists. There are some 'Lisps' for which this is not the case or not central.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
0

Atom is either a symbol, a character, a number, or null.

(define (atom? a)
  (or (symbol? a)
      (char? a)
      (number? a)
      (null? a)))

I think those are all the atoms that exist, if you find more add to the conditional expression. For example, if you think a string is an atom, add (string? a), :-). The absence of a definition for atom, allows you to define it the way you want. After all, Scheme does not know what an atom is.

In Lisp nil is an atom, so I've made null an atom. nil is also a list by simplification nil = (nil . nil), the same way the integral numbers are rational numbers by simplification, 2 = 2/1, 2 is an integral number, 2/1 is a rational number, as both are equals by simplification of the rational one; one says the integral number 2 is also a rational number. But the list predicate is already defined in Scheme, nothing to worry about.

About the question. As long as I am concerned Scheme has predicates only for class types, atom is not a class type, atom is an abstraction that incorporates several class types. Maybe that is the reason. But pair is not a class type either, but it does not incorporate several class types, and yet some may consider pair as a class type.

Atom means that a certain thing is not a compound thing. One reason not to include such a predicate is when the language allows you to define atomic types, so the pletora of atoms can grow wider and wider, and such a predicate would make no sense. I don't know if Scheme allows for this. I can only say that Scheme predicates (the built-in ones) are all specific. You can ask, is this an apple?, is this an orange?; but you cannot ask is this a fruit?. :-). Well, you can, if you do it yourself. Despite what a said, Scheme has a general predicate number?, and number specific predicates, integer?, rational?, real?; notwithstanding, number can be thought of as a class type (the other predicates refer to sub-types of number), whereas atom is not (at least in Scheme).

Note: class types: types that belong to a certain class of things. Example:

number, integer, real, rational, character, procedure, list, vector, string, etc.

Alfgaar
  • 172
  • 1
  • 7