← Back to context

Comment by skydhash

14 days ago

> what are for most coders three clearly different logical concerns

That's the imperative model which foundations is the Turing machine. Lisp comes from lambda calculus and you're not doing the above really. At it's core there's the value (or the symbol that's represent it), then the abstraction, which defines how to get the value, and the application, which let you know with what to replace unknowns (variables) in your abstraction so you can get the value. And it's recursive.

A program can be a value (not that useful), an abstraction (kinda like a nice theorem), or an application (the useful choice). Defining a function is creating a named abstraction, which is just a special value. Invoking a function is applying the parameters to that abstraction, which means replacing variables to get a more simplified version with the goal to finally have a value. If you can't get a value, that means the result is still an abstraction and then you still have to do more applications.

You either have a symbol or atom (which is a value) or you have a list which is an application (except the empty list, which is the same thing as nil). An abstraction is created by special forms like (defun foo (bar) ...) in CL. but the result of the latter is still a symbol. An atom is equivalent to itself, and a list is equivalent to having applied the abstraction represented by the first element to the rest. Anything else is either special forms, macros, or syntactic sugar.

So unless you're applying imperative thinking to the lambda calculus model, there's no confusion possible.

I don't have to be confused by it to dislike how it ends up working out in actual code, even "clean" code, in terms of ease of understanding and maintainability.