From PHP to Clojure



Clojure (pronounced closure) — modern dialect of Lisp, a programming language is a General purpose dynamically typed and encourages functional programming. The author of the language rich Hickey introduced his creation in 2007, since the language is Mature and has reached version 1.7, released 30 June 2015.

One of the main concepts of the language is to work on an existing platform. Rich Hickey decided not to write their execution environment, a garbage collector, etc. — this would require much effort, it's easier to use a ready-made platform such as the JVM .NET, JavaScript. To date, two of the most actively developing directions: Clojure on the JVM (it has reached version 1.7 not so long ago) and ClojureSrcipt is a subset of the language that compiles to JavaScript to run in the browser and on Node.js. Version .NET is developing not so actively and behind the JVM implementation. I searched the Internet and found a few dead Clojure implementations: Go, PHP, Python and Perl.

In this article I want to talk about Clojure, showing examples in comparison with PHP, based on a series of screencasts in English From PHP to Clojure.

PHP and Clojure are two completely different languages. When you first see Clojure, you can think that this is some kind of freaky JSON. In fact, Clojure is a very powerful and elegant language.

Comparing with PHP, many aspects of language have direct analogues. Others will become clearer if to look at them from the right angle.

the

Anonymous functions, Closure & Clojure


Start with a small retreat to sort out the terminological confusion. Anonymous functions and closures were introduced in PHP 5.3, and if you look closely at documentation, we can see that anonymous functions in PHP are implemented using the Closure class. The word "Closure", in turn, translates as "closure" and writing is very similar to the name of the Clojure (note the letter j in the middle). Lest we get confused further, we will use the term "Anonymous function" for anonymous functions and "Closure" for the effect of lexical visibility of a variable is when in PHP in description anonymous function uses use(...). In Clojure, respectively, also has anonymous functions and closures.

the

Namespaces


Here are very many similarities between PHP and Clojure: namespaces consist of parts which correspond to the physical location of the files. Only two differences: in Clojure, the separator is a dot and the names of namespaces is called with a lowercase letter.

the
// PHP
namespace Foo\Bar\Baz;


the
;; Clojure
(ns foo.bar.baz)


the

Syntax


In Clojure, the function name and its arguments are inside brackets, for example
(count foo) ;; Clojure
, equivalent to
count($foo) // PHP


Now look at a more complex code:



At first glance, nothing. But there is a little trick: imagine an xml-like language for templating, which has if, for, or tag assigns a value to a variable:



Now replace the angle brackets to parentheses:



Beg a little, removing the names of the attributes, and some extra quotes tags:



And in the toga get Clojure! (actually, it's not Clojure, but it's very close):



With a little practice, you'll find that this syntax is even easier than good old classic C-like. The Clojure syntax is compact, expressive and quite easy to read.
The only thing that can be confusing is the number of closing parentheses at the end of that have taken on the same line:



However, in real life it's not a problem, as all modern editors and ides can highlight matching brackets.

Going back to PHP, the syntax to all of us seems simple enough. But let's count!

There is a separate syntax for defining variables, function definitions and definitions of global variables inside functions:



The syntax for structures if, switch, and other control structures:



The syntax for defining classes, properties and methods within a class, the syntax for creating instances of a class, access the properties and call the methods:



And the syntax for anonymous functions and closures:



In Clojure, by contrast, the syntax is very simple! Need to know three basic things: Value, Symbol and List (this is not 100% syntax, but for the most part you will be working with these concepts).

Value (value) — this data, such as number, string or a regular expression:

the
2
"Hello, World"
#"\d+"

Symbol (symbol) — the names, the names of variables, functions, etc. Usually, the symbols indicate what kind of data (Value):
the
def
map
db
my-symbol

List (list) — this is a pair of parentheses, between which is located the value (value), symbols (symbol) or other lists (list). I.e. you can create nested lists and lists containing different types of things: values, symbols, and lists interspersed.

the
(some-symbol "Some Value" ("nested list with value" and-symbol))

And this is all the syntax of Clojure!

But wait, where are descriptions of functions, control structures (if/else), loops, and so on?

All present in Clojure, but in terms of General syntax, which I just did.

For example, if does not exist as a separate syntax, it's just a list containing the symbol if followed by a condition, then what to perform when in the case of the truth and what to do otherwise. Moreover, all these design elements in turn are either a value or a symbol or a list:


Same thing with functions. A function is defined as a list containing the values, symbols, and other lists. Similar situation with the definition of variables, namespaces, and other things. In other words, instead of having to introduce a separate syntax for each feature of the language, everywhere, use the generic syntax of lists, symbols and values.

This leads to additional buns, for example, now you do not need to remember the precedence of operations.

Precedence of operators in PHP:


To add two numbers, you need to open a parenthesis, then write the symbol +, then through a space two numbers requiring addition and close the bracket:

the
(+ 3 4)

— get a list consisting of the symbol and two values. Sign + is a valid symbol in Clojure and it refers to a function that performs the addition of subsequent elementov in the list.

Another example with the precedence of operations: 4 + 3 / 2 = ?

Depending on what kind of priority do you want, you will write either this:

the
(/ (+ 4 3) 2) ;; 3.5

Or this:

the
(+ 4 (/ 3 2)) ;; 5.5

and there is no automatic priority of operations, you always explicitly specify the order of execution of actions.

the

Symbols


Symbols in Clojure are intended for naming different things. Please note that they are not called variables, because data in Clojure is immutable by default. In other words, the symbols point to immutable data.
Under the agreement, it is customary to write the names of the characters lowercase, separating words with a hyphen. Symbols cannot begin with digits in the rest of the following signs:



Boolean values accepted to finish with a question mark (in PHP, these variables usually begin with the prefix is):



In addition to the list of allowed characters for use in names of characters, it is also worth mentioning and reserved, which may not be part of the name:



Some of the signs are in the "grey zone" — you can use them in names of characters in the current version of Clojure, but there is no guarantee that they will not be reserved



the

scalars



Numbers


As in PHP, Clojure has integers and floating point numbers. However, unlike PHP, there are two type of integers: Integer and BitInt. The second type can store arbitrarily large values, as far as the RAM. To explicitly tell the compiler that you want to use BigInt, you need to put the letter M after the number. Similarly, in floating point, but there is a big letter N at the end.



You can also use a different number system:



Clojure supports work with fractions! Compare PHP code:

the
$x = 4 / 3; //the result is 1.33333...
$y = $x * 3; //result 3.99999....

And in Clojure:

the
(/ 4 3) ;; the result - the fraction 4/3 is represented by a special data type Ratio
(* 4/3 3) ;; result 4



Strings in Clojure are Java strings. They do not support interpolation, ie you can not just take and paste it inside some variable in the middle of the line, but you can use a special sequence of type \nfor translation. In addition, strings can be multiline



Unlike PHP, strings must not be enclosed in single quotes:



In Clojure there is a separate type of Character — single-character "strings", they are written without quotes but with the backslash at the beginning. Please note that \n is not a newline, it's just the letter n.

There is also a set of predefined Characters, which are used to define newline, tab, etc.: \newline, \tab, \backspace.

It is also possible to separate unicode characters, for example \u263a.

Finally available and octal notation: \o003 is Ctrl+C.



Regular expressions


A regular expression starts with the # character and then the expression in quotation marks: #"\d+". Under the hood uses regular expressions from Java, so pay attention to the Java syntax:



a little More about scalar types


Type Nil can be a single value nil (similar to Null in PHP).

Type Bool takes two values true and false. However, unlike PHP, only two values nil and false perceived as false. For comparison, a value of 0 and "" (empty string) in Clojure will be interpreted as truth, while in PHP they are lie:



Keyword


In Clojure there is a data type called Keyword, but it is not the best key words to which we are accustomed in PHP (like if, for, etc.). Keywords always start with the colon symbol. You create keywords in the program code and their only value is they. You cannot assign a value to the keyword. In the screenshot below, the only possible value for keyword pi is itself pi.


But why you need keywords, if they are settable? In PHP there is a define to define a global constant value. Often the values themselves are defined in the define's, have no meaning, we only want to define some reserved name to use as array key or a parameter of the function.

For example, in PHP there is a function str_pad, which is complementary to one string with another string to a specified length. The last parameter of this function is $pad_type host one of three values: STR_PAD_RIGHT, STR_PAD_LEFT, STR_PAD_BOTH. Under the hood of these three constants have the values 0, 1 and 2 respectively. In fact, they could have any values of type 265, 1337 and 9000 is not important.

In Clojure we would use the keywords :str-pad-right, :str-pad-left, :str-pad-both — they don't have any other values under the hood, they are equal to themselves and that's exactly what I need!

More often, key words can be found in associative arrays:
the
{:first-name "Irma", :last-name "Gerd"}


But the topic of associative arrays and other data types for working with collections is beyond the scope of this article.

the

Instead of a conclusion — useful links


I hope I got you excited with Clojure, because it is possible to make great web apps, as you can read in a couple of articles published recently on habré: and .

Since the focus of article was comparison of Clojure syntax and PHP separately will provide a link to the table with examples of basic expressions
PHP vs Clojure.

Come listen to and ask your questions live to the conference FPCONF on 15 August 2015 in Moscow, where there will be presentations on web development in Clojure and ClojureScript.
Article based on information from habrahabr.ru

Comments

Popular posts from this blog

Powershell and Cyrillic in the console (updated)

Active/Passive PostgreSQL Cluster, using Pacemaker, Corosync

Automatic deployment ElasticBeanstalk using Bitbucket Pipelines