Title: Showing some Common Lisp features
       Author: Solène
       Date: 05 December 2017
       Tags: lisp
       Description: 
       
       # Introduction: comparing LISP to Perl and Python
       
       We will refer to Common LISP as CL in the following article.
       
       I wrote it to share what I like about CL. I'm using Perl to compare CL
       features. I am using real world cases for the average programmer. If
       you are a CL or perl expert, you may say that some example could be
       rewritten with very specific syntax to make it smaller or faster, but
       the point here is to show usual and readable examples for usual
       programmers.
       
       This article is aimed at people with programming interest, some basis
       of programming knowledge are needed to understand the following. If
       you know how to read C, Php, Python or Perl it should be
       enough. Examples have been choosed to be easy.
       
       I thank my friend killruana for his contribution as he wrote the
       python code.
       
       ## Variables
       
       
       ### Scope: global
       
       **Common Lisp code**
       
           (defparameter *variable* "value")
       
       Defining a variable with defparameter on top-level (= outside of a
       function) will make it global. It is common to surround the name of
       global variables with **\*** character in CL code. This is only for
       readability for the programmer, the use of **\*** has no
       incidence.
       
       **Perl code**
       
           my $variable = "value";
       
       **Python code**
       
           variable = "value";
       
       ### Scope: local
       
       This is where it begins interesting in CL. Declaring a local variable
       with **let** create a new scope with parenthesis where the variable
       isn't known outside of it. This prevent doing bad things with
       variables not set or already freed. **let** can define multiple
       variables at once, or even variables depending on previously declared
       variables using **let\***
       
       
       **Common Lisp code**
       
           (let ((value (http-request)))
             (when value
               (let* ((page-title (get-title value))
                      (title-size (length page-title)))
                 (when page-title
                   (let ((first-char (subseq page-title 0 1)))
                     (format t "First char of page title is ~a~%"
       first-char))))))
       
       **Perl code**
       
           {
               local $value = http_request;
               if($value) {
                   local $page_title = get_title $value;
                   local $title_size = get_size $page_title;
                   if($page_title) {
                       local $first_char = substr $page_title, 0, 1;
                       printf "First char of page title is %s\n", $first_char;
                   }
               }
           }
       
       a if/while/for/foreach or plain brakets.
       
       **Python code**
       
           if True:
               hello = 'World'
           print(hello) # displays World
       
       There is no way to define a local variable in python, the scope of the
       variable is limited to the parent function.
       
       ## Printing and format text
       
       CL has a VERY powerful function to print and format text, it's even
       named format. It can even manage plurals of words (in english only) !
       
       **Common Lisp code**
       
           (let ((words (list "hello" "Dave" "How are you" "today ?")))
             (format t "~{~a ~}~%" words))
       
       format can loop over lists using **~{** as start and **~}** as end.
       
       **Perl code**
       
           my @words = @{["hello", "Dave", "How are you", "today ?"]};
           foreach my $element (@words) {
               printf "%s ", $element;
           }
           print "\n";
       
       **Python code**
       
           # Printing and format text
           # Loop version
           words = ["hello", "Dave", "How are you", "today ?"]
           for word in words:
               print(word, end=' ')
           print()
       
           words = ["hello", "Dave", "How are you", "today ?"]
           print(*words)
       
       
       ## Functions
       
       
       ### function parameters: rest
       
       Sometimes we need to pass to a function a not known number of
       arguments. CL supports it with **&rest** keyword in the function
       declaration, while perl supports it using the **@\_** sigil.
       
       **Common Lisp code**
       
           (defun my-function(parameter1 parameter2 &rest rest)
             (format t "My first and second parameters are ~a and ~a.~%Others
       parameters are~%~{    - ~a~%~}~%"
                     parameter1 parameter2 rest))
       
       
       **Perl code**
       
           sub my_function {
               my $parameter1 = shift;
               my $parameter2 = shift;
               my @rest = @_;
       
       parameters are\n",
                   $parameter1, $parameter2;
       
                   printf "    - %s\n", $element;
               }
           }
       
       
       **Python code**
       
           def my_function(parameter1, parameter2, *rest):
               print("My first and second parameters are {} and
       {}".format(parameter1, parameter2))
               print("Others parameters are")
               for parameter in rest:
                   print(" - {}".format(parameter))
       
       
       The trick in python to handle rests arguments is the wildcard
       character in the function definition.
       
       ### function parameters: named parameters
       
       CL supports named parameters using a keyword to specify its
       name. While it's not at all possible on perl. Using a hash has
       parameter can do the job in perl.
       
       CL  allow to choose a default value if a parameter isn't set,
       it's harder to do it in perl, we must check if the key is already set
       in the hash and give it a value in the function.
       
       **Common Lisp code**
       
           (defun my-function(&key (key1 "default") (key2 0))
             (format t "Key1 is ~a and key2 (~a) has a default of 0.~%"
                     key1 key2))
       
       
       There is no way to pass named parameter to a perl function. The best
       way it to pass a hash variable, check the keys needed and assign a
       default value if they are undefined.
       
       **Perl code**
       
           sub my_function {
               my $hash = shift;
       
                   $hash->{key1} = "default";
               }
       
                   $hash->{key2} = 0;
               }
       
                   $hash->{key1}, $hash->{key2};
           }
       
       
       **Python code**
       
           def my_function(key1="default", key2=0):
               print("My key1 is {} and key2 ({}) default to 0.".format(key1,
       key2))
       
       
       
       ## Loop
       
       CL has only one loop operator, named loop, which could be seen as an
       entire language itself. Perl has do while, while, for and foreach.
       
       
       
       
       ### loop: for
       
       **Common Lisp code**
       
           (loop for i from 1 to 100
              do
                (format t "Hello ~a~%" i))
       
       **Perl code**
       
           for(my $i=1; $i <= 100; $i++) {
               printf "Hello %i\n";
           }
       
       **Python code**
       
           for i in range(1, 101):
              print("Hello {}".format(i))
       
       
       
       ### loop: foreach
       
       **Common Lisp code**
       
           (let ((elements '(a b c d e f)))
             (loop for element in elements
                counting element into count
                do
                  (format t "Element number ~s : ~s~%"
                          count element)))
       
       **Perl code**
       
           # verbose and readable version
           my @elements = @{['a', 'b', 'c', 'd', 'e', 'f']};
           my $count = 0;
           foreach my $element (@elements) {
               $count++;
               printf "Element number %i : %s\n", $count, $element;
           }
       
           for(my $i=0; $i<$#elements+1;$i++) {
               printf "Element number %i : %s\n", $i+1, $elements[$i];
           }
       
       **Python code**
       
           # Loop foreach
           elements = ['a', 'b', 'c', 'd', 'e', 'f']
           count = 0
           for element in elements:
               count += 1
               print("Element number {} : {}".format(count, element))
       
           elements = ['a', 'b', 'c', 'd', 'e', 'f']
           for index, element in enumerate(elements):
               print("Element number {} : {}".format(index, element))
       
       
       ## LISP only tricks
       
       
       
       
       ### Store/restore data on disk
       
       The simplest way to store data in LISP is to write a data structure
       into a file, using **print** function. The code output with **print**
       can be evaluated later with **read**.
       
       **Common Lisp code**
       
           (defun restore-data(file)
             (when (probe-file file)
               (with-open-file (x file :direction :input)
                 (read x))))
       
             (with-open-file (x file
                                :direction :output
                                :if-does-not-exist :create
                                :if-exists :supersede)
               (print data x)))
       
           (save-data "books.lisp" *books*)
           (defparameter *books* (restore-data "books.lisp"))
       
       This permit to skip the use of a data storage format like XML or
       JSON. Common LISP can read Common LISP, this is all it needs. It can
       store objets like arrays, lists or structures using plain text
       format. **It can't dump hash tables directly.**
       
       
       ### Creating a new syntax with a simple macro
       
       Sometimes we have cases where we need to repeat code and there is no
       way to reduce it because it's too much specific or because it's due to
       the language itself. Here is an example where we can use a simple
       macro to reduce the written code in a succession of conditions doing
       the same check.
       
       We will start from this
       
       **Common Lisp code**
       
           (when value
             (when (string= line-type "3")
               (progn
                 (print-with-color "error" 'red line-number)
                 (log-to-file "error")))
             (when (string= line-type "4")
               (print-with-color text))
             (when (string= line-type "5")
               (print-with-color "nothing")))
       
       to this, using a macro
       
       **Common Lisp code**
       
           (defmacro check(identifier &body code)
             `(progn
                (when (string= line-type ,identifier)
                ,@code)))
       
             (check "3"
                    (print-with-color "error" 'red line-number)
                    (log-to-file "error"))
             (check "4"
                    (print-with-color text))
             (check "5"
                    (print-with-color "nothing")))
       
       The code is much more readable and the macro is easy to
       understand. One could argue that in another language a switch/case
       could work here, I choosed a simple example to illustrate the use of a
       macro, but they can achieve more.
       
       
       
       
       ### Create powerful wrappers with macros
       
       I'm using macros when I need to repeat code that affect variables.  A
       lot of CL modules offers a structure like **with-something**, it's a
       wrapper macro that will do some logic like opening a database,
       checking it's opened, closing it at the end and executing your code
       inside.
       
       Here I will write a tiny http request wrapper, allowing me to write
       http request very easily, my code being able to use variables from the
       macro.
       
       **Common Lisp code**
       
           (defmacro with-http(url)
             `(progn
                (multiple-value-bind (content status head)
                    (drakma:http-request ,url :connection-timeout 3)
                  (when content
                    ,@code))))
       
             (format t "We fetched headers ~a with status ~a. Content size is
       ~d bytes.~%"
                     status head (length content)))
       
       In Perl, the following would be written like this
       
       **Perl code**
       
           sub get_http {
               my $url = $1;
               my %http = magic_http_get $url;
               if($http{content}) {
                   return %http;
               } else {
                   return undef;
               }
           }
       
               local %data = get_http "https://dataswamp.org/";
               if(%data) {
                   printf "We fetched headers %s with status %d. Content size
       is %d bytes.\n",
                       $http{headers}, $http{status}, length($http{content});
               }
           }
       
       The curly brackets are important there, I want to emphase that the
       **local** %data variable is only available inside the curly
       brackets. Lisp is written in a successive of local scope and this is
       something I really like.
       
       **Python code**
       
           import requests
           with requests.get("https://dataswamp.org/") as fd:
               print("We fetched headers %s with status %d. Content size is %s
       bytes." \
                           % (list(fd.headers.keys()), fd.status_code,
       len(fd.content)))