title | date | author | tags | keywords | categories | reward | reward_title | reward_wechat | reward_alipay | source_url |
---|---|---|---|---|---|---|---|---|---|---|
Kotlin gets support for S-expressions |
2014-04-01 11:33:00 -0700 |
Andrey Breslav |
官方动态 |
false |
Have a nice Kotlin! |
Kotlin is always happy to learn from other programming languages, and this is why we decided to support S-expressions , the empowering concept of LISP . The main motivation behind this is the compatibility with Clojure , the LISP for the JVM. Clojure is well-known for its solid libraries, particularly the ones used for concurrency and read-only data structures. To facilitate interoperability with LISP (and Clojure libraries in particular), Kotlin now allows expressions like this one:
{% raw %}
{% endraw %}(println (
(lambda (arg1)
(+
"first lambda: "
arg1
(lambda (arg2)
(+ "second lambda: " arg1 arg2)
)
)
) foo "bar"
))
{% raw %}
{% endraw %}This is only to give you the taste. Now, let’s explain the constructs one-by-one.
First of all, there’s only one new syntactic construct added, namely the S-expression. It has the form
{% raw %}
{% endraw %}(A B C ...)
{% raw %}
{% endraw %}where A, B, C … may themselves be S-expressions or other Kotlin expressions. Now, most operations in LISP are written in prefix form, and if you want, you can write addition in this style in Kotlin:
{% raw %}
{% endraw %}(+ 1 two 3)
{% raw %}
{% endraw %}Note that literals (‘1’, ‘3’) can be mixed with other expressions (e.g. ‘two’). LISP originally stands for LISt Processing, so the literals for lists are very important:
{% raw %}
{% endraw %}(list abc "def" ghi "jkl")
{% raw %}
{% endraw %}This create a list of four objects. Normal Kotlin functions can be called in the LISP-manner, so to print the list above, we can say:
{% raw %}
{% endraw %} (println
(list abc "def" ghi "jkl")
)
{% raw %}
{% endraw %}Lambda expressions also have a LISP-form:
{% raw %}
{% endraw %}(lambda (arg1) (+ 1 arg1 2))
{% raw %}
{% endraw %}And the following code demonstrates closures:
{% raw %}
{% endraw %} (println (
(lambda (arg1)
(+
"first lambda: "
arg1
(lambda (arg2)
(+ "second lambda: " arg1 arg2)
)
)
) foo "bar"
))
{% raw %}
{% endraw %}You can find the above examples (and some more) here . They are runnable, and you can play with the code. Disclaimer: it’s only a prototype.
Unfortunately, at this stage our support for S-expressions is somewhat limited. Due to some issues connected with parsing, an S-expression can only be of odd length. We are working on removing this limitation. Also, when defining a named function as an S-expression, its name has to be preceded with a dot (not to be confused with the Dot operator mentioned below):
{% raw %}
{% endraw %}(defun .baz (a, b, c) (+ a b c))<span style="font-size: 16px;">
</span>
{% raw %}
{% endraw %}Many of you were waiting eagerly for us to release the Dot operator . Now it’s implemented, compiler and IDE plugin are downloadable here , thanks to jgl87 .