Прошел ClojureScript Koans — набор простых задачек/примеров для изучения ClojureScript. Сам по себе ClojureScript — это язык компилируемый в JavaScript, т.е. для браузера или для Node, поэтому сравнение с PHP (чисто backend языком) выглядит странно. Правильнее было бы сравнить PHP и Clojure, который запускается на JVM и предназначен для написания server-side приложений. Однако, что касается синтаксиса и базовых возможностей, здесь ClojureScript ничем не отличается от Clojure. Так что я решил озаглавить этот пост как «PHP vs Clojure«, не смотря на то, что он основан на ClojureScript Koans.
Приведённые в таблице выражения не полностью эквивалентны. Нужно учитывать, что Clojure (и ClojureScript) используют неизменяемые структуры данных, в то время как в PHP некоторые методы меняют массивы по месту (по ссылке) или имеют другие сайд-эффекты (например, изменение внутреннего указателя на текущий элемент).
PHP | Clojure |
---|---|
true = true | (= true true) |
1 + 1 | (+ 1 1) |
2 != 3 | (not= 2 3) |
[1, 2, 3, 4, 5] | '(1 2 3 4 5) или [1 2 3 4 5] |
['key1' => 'value1', 'key2' => 'value2'] | {'key1' } |
reset([1, 2, 3, 4, 5]) | (first '(1 2 3 4 5)) |
$list = [1, 2, 3, 4, 5]; $rest = $list; array_shift($rest); | (rest '(1 2 3 4 5)) |
count(['dracula', 'dooku', 'chocula']) | (count '(dracula dooku chocula)) |
$list = ['b', 'c', 'd', 'e']; array_unshift($list, 'a'); | (cons :a '(:b :c :d :e)) или (conj '(:b :c :d :e) :a) |
reset(['a', 'b', 'c', 'd', 'e']) | (peek '(:a :b :c :d :e)) |
$list = [1, 2, 3, 4, 5]; $rest = $list; array_shift($rest); | (pop '(:a :b :c :d :e)) |
null | nil |
$vector = [111, 222]; $vector[] = 333; | (conj [111 222] 333) |
$vector = ['penaut', 'butter', 'and', 'jelly']; $last = end($vector); |
(last [:peanut :butter :and :jelly]) |
['penaut', 'butter', 'and', 'jelly'][3] | (nth [:peanut :butter :and :jelly] 3) |
array_slice(['peanut', 'butter', 'and', 'jelly'], 1, 3) | (subvec [:peanut :butter :and :jelly] 1 3) |
[1, 2, 3] === [1, 2, 3] | (= (list 1 2 3) (vector 1 2 3)) |
['a' => 1, 'b' => 2]['b'] | (get {:a 1, :b 2} :b) или ({:a 1, :b 2} :b) или (:b {:a 1, :b 2}) |
$map = ['a' => 1, 'b' => 2]; $result = array_key_exists('c', $map) ? $map['c'] : null; | (get {:a 1, :b 2} :c) |
$map = ['a' => 1, 'b' => 2]; $result = array_key_exists('c', $map) ? $map['c'] : 'key-not-found'; | (get {:a 1, :b 2} :c :key-not-found) |
array_key_exists('b', ['a' => null, 'b' => null]) | (contains? {:a nil, :b nil} :b) |
$map = [1 => 'January']; $map[2] = 'February'; | (assoc {1 "January"} 2 "February") |
$map = [1 => 'January', 2 => 'February']; unset($map[2]) | (dissoc {1 "January", 2 "February"} 2) |
$keys = array_keys([2010 => 'Vancouver', 2014 => 'Sochi', 2006 => 'Torino']); sort($keys) | (sort (keys {2010 "Vancouver", 2014 "Sochi", 2006 "Torino"})) |
$vals = array_values([2006 => 'Torino', 2010 => 'Vancouver', 2014 => 'Sochi']); sort($vals) | (sort (vals {2006 "Torino", 2010 "Vancouver", 2014 "Sochi"})) |
function square($n) {return $n * $n;} square(9); |
(defn square [n] (* n n)) (square 9) |
false === (4 === 5) ? 'a' : 'b' | (if (false? (= 4 5)) :a :b) |
null === 0 | (nil? 0) |
nulll === 0 ? 'a' : null | (if (nil? 0) :a) |
empty([]) | (empty? ()) |
$x === 1 ? "result1" : ($x === 2 ? "result2" : "result3") | (cond (= x 1) "result1" (= x 2) "result2" :else "result3" |
!(0 === $x) ? "not zero" : "zero" | (if-not (zero? x) "not zero" "zero") |
switch($x) {case "value1": $result = "result1"; break; case "value2": $result = "result2"; break; default: "default result";} | (case x "value1" "result1" "value2" "result2" "default result") |
array_map(function($x) {return 4 * $x;}, [1, 2, 3]); | (map (fn [x] (* 4 x)) [1 2 3]) |
array_map('is_null', ['a', 'b', null, 'c', 'd'] | (map nil? [:a :b nil :c :d]) |
array_reduce([1, 2, 3, 4], function($a, $b) {return $a * $b;}, 100) | (reduce (fn [a b] (* a b)) 100 [1 2 3 4]) |
range(1, 4) | (range 1 5) |
range(0, 4) | (range 5) |
array_fill(0, 10, "a") | (repeat 10 "a") |
$result = []; foreach(['top', 'middle', 'bottom'] as $row) { foreach(['left', 'middle', 'right'] as $column) { $result[] = [$row, $column]; } } |
(for [row [:top :middle :bottom] column [:left :middle :right]] [row column]] |