From PHP to Clojure - pt1
Published: 2021-12-15 12:08:35

Summary
- [Knowing the languages](#knowing-the-languages)
- [File extension](#file-extension)
- [Environment](#environment) 
- [Dependency manager](#dependency-manager) 
- [Typehint](#typehint) 
- [Data structures](#data-structures) 
- [Hello world](#hello-world)

August 17, year 2021. Recently I started working with Clojure after a long time using PHP, Java, Javascript. I was fear about learn this new technology.

I decided write my first impression so far. If you are intending change your stack or just wanna do it for fun, it could help you.

## Knowing the language
### PHP
May you already read  [PHP](https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/), this article was wrote in 2012. In 2021 the PHP environment has grow a lot as syntax and  [performance](https://www.techempower.com/benchmarks/). Nowadays you should use typehint, you can use improves like  [Swoole ](https://www.swoole.co.uk/). But it still have some inconsistencies in the language, you can read more about how impressive PHP can be to nowadays on this [link](https://bulletproofphp.dev/yes-php-is-worth-using) .

### Clojure
It is a Lisp based language, and commonly Lisp was used to mathematic propose; and may you have seen Clojure examples like dividing, summing or handling with numbers and math stuffs on the internet, but it could be used in another ways. Immutability also is the best and it provides a thread safe programming, all the benefits of functional programming can be a a good approach.

## Environment
Under the hood, Clojure use Java environment, so you need the SDK and JVM to run your project, by the way, you can use Java classes and features in your project. The same affirmative is used about how erros's stack trace are shown and you still not free from NullPointerException.
Clojure is a compiled language, so unlike php, you need to compile first in order to generate the jar file. May you are wonder if you have to wait the compiler always during your test, but thats not true. You can use  [REPL](https://clojure.org/guides/repl/introduction) (standing for Read-Eval-Print Loop) and it will allow you to interact with a running Clojure program and modify it, by evaluating one code expression.
To run a php script, you need install PHP in you system (mr obvious) and it is too simple on Linux based system, otherwise if you want run a script over http you need a PHP-Fpm or runners like  [Roadrunner](https://roadrunner.dev/) or Swoole.

## Dependency manager
As you have  [composer](https://getcomposer.org/)  for PHP, you have  [Leiningen](https://leiningen.org/) for Clojure projects. With Leiningen you can start a new project and pull libraries dependencies to use in your project. It works like Composer with a set of commands to setup you project setting, as you need a composer.json you need a project.clj do write the configurations.
Below you have a comparison between this two file configurations for clojure and PHP

```clj
(defproject my-project "0.1.0-SNAPSHOT"
  :description "my-project-desc"
  :url ""
  :license {:name "MIT"}
  :dependencies [[lib-dep-1 "0.0.1"]]
  :aliases {"script-here" [ "./command"  "arguments"]})
``` 


```json
{
    "name":"my-project",
    "description":"my-project-desc",
    "license": "MIT",
    "requires" : {
        "lib-dep-1": "0.0.1"
    },
    "scripts": {
          "script-here": [
              "./command",
              "arguments"
          ],
    }
}
``` 

## Typehint
Since PHP 7 an so on, typehints has been becoming a popular and necessary feature in PHP, and before this version, you could use any kind of return types or arguments. Nowadays PHP > 8 become more strongly typed, but you will not find types in Clojure! May you are worried how it could work, Clojure is a functional language and it runs in a Java strongly typed environment, under the hood Clojure cast some primitive values. Functions like division could return a Ration, float or BigInt and you can find some examples  [here](https://clojure.org/reference/data_structures#_bigint_and_bigdecimal_literals) .
Otherwise you can use tools like  [clojure.spec](https://clojure.org/guides/spec) or  [Plumatic](https://github.com/plumatic/schema) to validate function's inputs and outputs. Daily I have been using Plumatic and I do love it how it useful and beautiful.

## Data structures
In Js we called object, in Python is called dictionary, in Java it is Hashes, in Clojure we called map. That is a very useful to represent key value structures.

PHP is an array based language, almost everything can be represented as an array. For Clojure we have an array too, but here it not work with any kind of structure like in php, we call it `vectors` and it is just a list, list of lists, list of values or list of maps. Recently PHP release a new function  [array_is_list](https://www.php.net/manual/en/function.array-is-list.php).

Set structure is my favorite, it is a collections of unique values, unlike `vector` you can't repeat a value in a set. In PHP we can repeat a value in an array, for example:

```php
$array = ['a', 'a']; // can exists a repeated value
```

```clj
#{:a :a}   ;This is not allowed

```

There are more data structures, but for now these are the most used for me daily. As soon as possible I publish more about how I keep using Clojure so on.

## Hello world

This article could not miss an example of hello-world in both languages. First you will need setup the dependencies wrote [here](#environment). 

To a simple script in PHP create a file hello-word.php
```php
<?php
echo 'Hello world';
```

Then execute
```shell
$ php hello-world.php
```
Last but not least, a Clojure example. Create a hello-word.clj

```clj
(print "hello-world")
```
You need start REPL and run the script

```shell
$ lein repl
=> (clojure.main/load-script "hello-world.clj")
```