May - Lisp

An early functional programming language

Description

This month we’re going to be looking at Lisp! Lisp is a functional programming language from the 50s but isn’t pure like Haskell. Yet it still makes good use of lambda calculus in its implementation, compared to most languages focusing on an imperative or object-orientated style, while keeping the potential high speeds of C.

Specification

The language seems almost like a mix of C, Haskell and Python, which is strange given how different the three are. Thus the challenge is to identify where Lisp differs from these three languages. What parts of it are similar to what? How do they fit together? Here are some specific questions:

  • If one algorithm is easier to write in Haskell, and another in Python, can both algorithms be implemented in Lisp with their shortest form?
  • How does typing compare between them. What are the benefits and drawbacks of such typing?
  • Does the code you write always work when compiled? Are runtime errors common?
  • What kind of functional data structure like Functors and Monads are available?
  • How nice is it to write some basic code in Lisp compared to Python?
  • How low level can it really get?

Compared to last weeks challenge, this is much less concrete, but with luck should be able to showcase the core of Lisp and where it fits into the set of languages. However, there is one final question to also answer: Should you use lisp? With luck we’ll have the answer by the end of this month.

Final Report

With the end of the month comes the next language evaluation. This one went into much less depth than Ada, focusing on the core concepts and accessibility of paradigm usage. I created a good number of questions to answer so starting off with them seems like a good plan:

If one algorithm is easier to write in Haskell, and another in Python, can both algorithms be implemented in Lisp with their shortest form?

To test this I attempted to implement fibbonacci in both an efficient and inefficient way:

defun fib2
(
    i; The index of the fibonacci to find
)
"More Efficient Fibonacci Finder"
(
    cond
    ((= i 1) (return-from fib2 (values 1 0)))
    (t
        (setf (values last1 last2) (fib2 (- i 1)))
        (return-from fib2 (values (+ last1 last2) last1))
    )
)

You can see that most of the result is overhead syntax (a lot of brackets), but the basic functionality is straightforward and works - it clearly supports functional programming. This also extends to first order functions and structured types which can also be passed. In the other side, it is clearly imperative as well, allowing support of multiple statements to be put in order, compared to Haskell which doesn’t do this.

In short, the answer is likely to be yes - especially as macros allow you to abstract concepts to work on them seperately, making the final implementation easier.

How does typing compare between them. What are the benefits and drawbacks of such typing?

As far as I can tell, Lisp is typed under the hood, but with no explicit typing when you create parameters etc. This allows you to reduces code while still being caught out for something invalid. However that can become a headache for fixing typing-based bugs unsure of what the type is/should be.

Does the code you write always work when compiled? Are runtime errors common?

Yes - the Lisp compiler seems to compile and run the code all at once, but when for example reading strings to add together, not being an int causes an error which would stop the program. This could become a big problem if you miss an error such as this up to production is finished and could do with a some kind of optional or similar system. Errors can be cause, as shown in calculator.lisp, but the process isn’t strightforward - not something I’d want to wrap around all my code.

What kind of functional data structure like Functors and Monads are available?

It seems like data structure are much less prevalent than in Haskell, making Lisp more accessable, but also potentially less flexible. These kinds of structure might be implemented by the programmer, but lose much of their value with the lack of explicit typing.

How nice is it to write some basic code in Lisp compared to Python?

I would say it’s less nice but still managable. Your main issue is simply getting the libraries and being left with brackets everywhere. But if you can live with both of them, the fact it doesn’t have any required code and the compiler both compiles and runs all at once, it’s actually not too bad as a scripting language.

How low level can it really get?

I looked into how to get pointers and it is possible, but requires a library. Most of the control seems to be using abstract data types. As the stack and heap are vividly clear in lisp, memory in Lisp is strightforward, making use of the first ever garbage collector. However if you want to take control of memory and CPU directly, lisp likely isn’t the language you’re looking for.

Should one use it?

I would say in my opinion, Lisp was a nice language for its time standing out from the others. But at this point it no longer holds as much reason to be used. The functional aspects for it don’t quite make up for the lack of explict typing and low level control, and the brackets make the syntax strange to anyone whose never used it before. Macros are indeed useful for replacing code, but C and C++ macros are more than sufficient and many other languages have good alternatives available. It’s definitely interesting to look at it now as a language from so long ago, but personally this will likely be the last I see of it.



Joseph Keane

Black-Photon