Search code examples
clojure

What's the difference between read-string and load-string in clojure?


I have the following form:

((read-string "+") 2 3)

It returns 3

I have two questions about this:

1) Why does the form above return 3 instead of nil or throwing an exception or anything else? How exactly is this form resolving? 2) What is returned from read-string in this case? And how is it different from if I had used load-string?


Solution

  • What you are actually doing is using a symbol as a function and passing arguments to it. You can read a related Q&A that covers this in more detail. From the answer:

    Now symbols can be used as functions (they implement the clojure.lang.IFn interface), but the way they act when used in this way is that they look themselves up in their argument, i.e. treat their argument as a map and perform a lookup inside it

    As stated in @akond's answer, read-string returns a symbol and load-string evaluates that too. You could trigger the same behavior by passing any other symbol:

    ((symbol 'hi) 2 3)
    ;; 3
    ('foo 2 3)
    ;; 3
    ('foo '{foo 2} 3)
    ;; 2
    ('foo 2)
    ;; nil since there is no default value provided
    

    If you are curious you can have a look at Symbol implementation in Clojure source code.