Lisp and Erlang Atoms, Ruby and Scheme Symbols. How useful are they?

前端 未结 13 1594
一个人的身影
一个人的身影 2020-12-12 18:08

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 consta

相关标签:
13条回答
  • 2020-12-12 18:29

    Atoms are literals, constants with their own name for value. What you see is what you get and don't expect more. The atom cat means "cat" and that's it. You can't play with it, you can't change it, you can't smash it to pieces; it's cat. Deal with it.

    I compared atoms to constants having their name as their values. You may have worked with code that used constants before: as an example, let's say I have values for eye colors: BLUE -> 1, BROWN -> 2, GREEN -> 3, OTHER -> 4. You need to match the name of the constant to some underlying value. Atoms let you forget about the underlying values: my eye colors can simply be 'blue', 'brown', 'green' and 'other'. These colors can be used anywhere in any piece of code: the underlying values will never clash and it is impossible for such a constant to be undefined!

    taken from http://learnyousomeerlang.com/starting-out-for-real#atoms

    With this being said, atoms end up being a better semantic fit to describing data in your code in places other languages would be forced to use either strings, enums or defines. They're safer and friendlier to use for similar intended results.

    0 讨论(0)
  • 2020-12-12 18:41

    In Scheme (and other members of the Lisp family), symbols are not just useful, they are essential.

    An interesting property of these languages is that they are homoiconic. A Scheme program or expression can itself be represented as a valid Scheme data structure.

    An example might make this clearer (using Gauche Scheme):

    > (define x 3)
    x
    > (define expr '(+ x 1))
    expr
    > expr
    (+ x 1)
    > (eval expr #t)
    4
    

    Here, expr is just a list, consisting of the symbol +, the symbol x, and the number 1. We can manipulate this list like any other, pass it around, etc. But we can also evaluate it, in which case it will be interpreted as code.

    In order for this to work, Scheme needs to be able to distinguish between symbols and string literals. In the example above, x is a symbol. It cannot be replaced with a string literal without changing the meaning. If we take a list '(print x), where x is a symbol, and evaluate it, that means something else than '(print "x"), where "x" is a string.

    The ability to represent Scheme expressions using Scheme data structures is not just a gimmick, by the way; reading expressions as data structures and transforming them in some way, is the basis of macros.

    0 讨论(0)
  • 2020-12-12 18:41

    The problem I have with similar concepts in other languages (eg, C) can be easily expressed as:

    #define RED 1
    #define BLUE 2
    
    #define BIG 1
    #define SMALL 2
    

    or

    enum colors { RED, BLUE  };
    enum sizes  { BIG, SMALL };
    

    Which causes problems such as:

    if (RED == BIG)
        printf("True");
    if (BLUE == 2)
        printf("True");
    

    Neither of which really make sense. Atoms solve a similar problem without the drawbacks noted above.

    0 讨论(0)
  • 2020-12-12 18:44

    You're actually not right in saying python has no analogue to atoms or symbols. It's not difficult to make objects that behave like atoms in python. Just make, well, objects. Plain empty objects. Example:

    >>> red = object()
    >>> blue = object()
    >>> c = blue
    >>> c == red
    False
    >>> c == blue
    True
    >>> 
    

    TADA! Atoms in python! I use this trick all the time. Actually, you can go further than that. You can give these objects a type:

    >>> class Colour:
    ...  pass
    ... 
    >>> red = Colour()
    >>> blue = Colour()
    >>> c = blue
    >>> c == red
    False
    >>> c == blue
    True
    >>> 
    

    Now, your colours have a type, so you can do stuff like this:

    >>> type(red) == Colour
    True
    >>> 
    

    So, that's more or less equivalent in features to lispy symbols, what with their property lists.

    0 讨论(0)
  • 2020-12-12 18:48

    In some languages, associative array literals have keys that behave like symbols.

    In Python[1], a dictionary.

    d = dict(foo=1, bar=2)
    

    In Perl[2], a hash.

    my %h = (foo => 1, bar => 2);
    

    In JavaScript[3], an object.

    var o = {foo: 1, bar: 2};
    

    In these cases, foo and bar are like symbols, i.e., unquoted immutable strings.

    [1] Proof:

    x = dict(a=1)
    y = dict(a=2)
    
    (k1,) = x.keys()
    (k2,) = y.keys()
    
    assert id(k1) == id(k2)
    

    [2] This is not quite true:

    my %x = (a=>1);
    my %y = (a=>2);
    
    my ($k1) = keys %x;
    my ($k2) = keys %y;
    
    die unless \$k1 == \$k2; # dies
    

    [1] In JSON, this syntax is not allowed because keys must be quoted. I don't know how to prove they are symbols because I don't know how to read the memory of a variable.

    0 讨论(0)
  • 2020-12-12 18:49

    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 {
      MSG_1,
      MSG_2,
      MSG_3
    };
    
    enum status_messages {
      STATUS_HEARTBEAT,
      STATUS_LOAD
    };
    

    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 :).

    0 讨论(0)
提交回复
热议问题