Lisp 与 Erlang 原子,Ruby 与方案符号。 它们有多大用处?

How useful is the feature of having an atom data type in a programming language?

A few programming languages have the concept of atom or symbol to represent a constant of sorts. There are a few differences among the languages I have come across (Lisp, Ruby and Erlang), but it seems to me that the general concept is the same. I am interested in programming language design, and I was wondering what value does having an atom type provide in real life. Other languages such as Python, Java, C# seem to be doing quite well without it.

I have no real experience of Lisp or Ruby (I know the syntaxes, but haven't used either in a real project). I have used Erlang enough to be used to the concept there.


Memor.の Also relevant:…
9 年多之前 回复
狐狸.fox You mean Lisp symbols, not atoms, right?
9 年多之前 回复


Atoms (in Erlang or Prolog, etc.) or symbols (in Lisp or Ruby, etc.)—from herein only called atoms—are very useful when you have a semantic value that has no natural underlying "native" representation. They take the space of C-style enums like this:


The difference is that atoms don't typically have to be declared and they have NO underlying representation to worry about. The atom monday in Erlang or Prolog has the value of "the atom monday" and nothing more or less.

While it is true that you could get much of the same use out of string types as you would out of atoms, there are some advantages to the latter. First, because atoms are guaranteed to be unique (behind the scenes their string representations are converted into some form of easily-tested ID) it is far quicker to compare them than it is to compare equivalent strings. Second, they are indivisible. The atom monday cannot be tested to see if it ends in day for example. It is a pure, indivisible semantic unit. You have less conceptual overloading than you would in a string representation in other words.

You could also get much of the same benefit with C-style enumerations. The comparison speed in particular is, if anything, faster. But... it's an integer. And you can do weird things like have SATURDAY and SUNDAY translate to the same value:


This means you can't trust different "symbols" (enumerations) to be different things and thus makes reasoning about code a lot more difficult. Too, sending enumerated types through a wire protocol is problematical because there's no way to distinguish between them and regular integers. Atoms do not have this problem. An atom is not an integer and will never look like one behind the scenes.

10.24 Arsanukaev: I know what you were commenting on. I was pointing out that if you convert the atom to a list, you're not comparing part of an atom any longer. You're comparing a list (as a string). Just like I can compare if the bottom end of an integer is "1671" by converting to a string -- it's not comparing integers any longer.
9 年多之前 回复
妄徒之命 I was commenting your "The atom monday cannot be tested to see if it ends in day for example." part WRT Erlang. Also, you forgot to put @ in front of my name, I wouldn't notice your comment :-)
9 年多之前 回复
10.24 Yasir: But a conversion, by definition, means it's no longer an atom (or a list, depending on direction).
9 年多之前 回复
妄徒之命 +1 But don't forget, for example, erlang:atom_to_list/1 and its opposite erlang:list_to_atom/1. They allow you to convert between atoms and strings (lists). It's discouraged though :-)
9 年多之前 回复

As a C programmer I had a problem with understanding what Ruby symbols really are. I was enlightened after I saw how symbols are implemented in the source code.

Inside Ruby code, there is a global hash table, strings mapped to integers. All ruby symbols are kept there. Ruby interpreter, during source code parse stage, uses that hash table to convert all symbols to integers. Then internally all symbols are treated as integers. This means that one symbol occupies only 4 bytes of memory and all comparisons are very fast.

So basically you can treat Ruby symbols as strings which are implemented in a very clever way. They look like strings but perform almost like integers.

When a new string is created, then in Ruby a new C structure is allocated to keep that object. For two Ruby strings, there are two pointers to two different memory locations (which may contain the same string). However a symbol is immediately converted to C int type. Therefore there is no way to distinguish two symbols as two different Ruby objects. This is a side effect of the implementation. Just keep this in mind when coding and that's all.

北城已荒凉 The same implementation is en Erlang for atoms, more or less.
9 年多之前 回复

Atoms are like an open enum, with infinite possible values, and no need to declare anything up front. That is how they're typically used in practice.

For example, in Erlang, a process is expecting to receive one of a handful of message types, and it's most convenient to label the message with an atom. Most other languages would use an enum for the message type, meaning that whenever I want to send a new type of message, I have to go add it to the declaration.

Also, unlike enums, sets of atom values can be combined. Suppose I want to monitor my Erlang process's status, and I have some standard status monitoring tool. I can extend my process to respond to the status message protocol as well as my other message types. With enums, how would I solve this problem?

enum my_messages {

enum status_messages {

The problem is MSG_1 is 0, and STATUS_HEARTBEAT is also 0. When I get a message of type 0, what is it? With atoms, I don't have this problem.

Atoms/symbols are not just strings with constant-time comparison :).

共13条数据 首页 2
Csdn user default icon