CL-USER> (setf universe (find-class 't)) #<BUILT-IN-CLASS T> CL-USER> (typep universe universe) T
What, you say, mathematicians just have to use Haskell ??
Stop right there, and read this.
Technically, there’s nothing new to see here at all. Lisp is high-level and low-level. Lisp is multi-paradigm. Lisp has uniform syntax. Blah blah blah. You’ve heard it all.
Still, some people seem to require an “argument from authority” (and usually still keep looking) … in which case you might be persuaded by this.
An extract (describing how
defgeneric can be handily abused to yield whatever you like):
For example, a mathematician who installs under CLOS the traditional mathematical categories must organize his work as follows:
defclassstatements will be used to define what a “set” object is, what a “group” object is, what a “chain complex” object is, and so on.
defgenericstatements will be used to define functions working on these objects, but these “functions” are traditionally called in this case functors in mathematics; therefore one
defgenericstatement for the sum functor, another
defgenericfor the classifying space functor, and so on.
Finally each generic function will have various methods to adapt the generic function to specific cases; for example the product of two objects of some category is also an object of this category with the corresponding structure to be defined. Therefore one product method for the sets, another product method for the magmas, another method for the monoids, and so on. The
change-classfunctions will allow these methods to possibly refer to the less specific ones.
I came across [this paper] recently, and it challenged some of the thoughts/assumptions that had been building in my mind for a while (it discusses Scheme vs Miranda, but you can imagine Lisp vs Haskell instead).
It also mirrors a short email exchange I had with someone who I expected to be a Scheme/Lisp “champion”, but who gently led me down from my gas balloon of hype.
Yes, S-expressions are great, and one can fall in love with them, and the notion of “building material” for a language to build an application or solve a problem, but there’s no point being dogmatic about them.
Also, another tangential perspective: people consider Paul Graham a big advocate of Lisp, but in my opinion there is no one who has harmed the cause of Common Lisp more than Paul Graham.
Instead of praising the language that allowed him to build his own “killer app”, or teaching the specific details of his implementation, or his own work with the language, what did he proceed to do instead? Ask everyone to wait for his “perfect language” (i.e. stop using Common Lisp!!), and write inflated, abstract articles attracting only language lawyers and the my-language-is-longer-than-yours crowd. Sheesh.
I came across this post talking about numerical speed in Clojure, so I thought I would try out the equivalent in Common Lisp (Clozure CL) on my Macbook:
CL-USER> (let* ((arr-size 3000000) (double-arr (make-array arr-size :element-type 'single-float))) (dotimes (i arr-size) (setf (aref double-arr i) (random 1.0))) (time (loop for i from 0 below arr-size summing (aref double-arr i)))) (LOOP FOR I FROM 0 BELOW ARR-SIZE SUMMING (AREF DOUBLE-ARR I)) took 45,649 microseconds (0.045649 seconds) to run. During that period, and with 4 available CPU cores, 45,558 microseconds (0.045558 seconds) were spent in user mode 57 microseconds (0.000057 seconds) were spent in system mode 1500183.5
45 milliseconds, not bad.
What if you did the following:
- Take a chromebook
- Modify the chromium build running to run Sbcl within it.
- Create lisp bindings to the internal surface, so that all UI elements can be created and manipulated within the Lisp image.
- Allow downloading, compiling and running arbitrary lisp code
- One of the tabs is always a Repl
- Add a caching filesystem that would persist part or whole of the image
… might this create a modern-day Lisp machine? Maybe.
Did I miss anything obvious here? If not, this sounds doable in a few years.
I’m lazy, do you if you like this idea (I’m sure there’s a guaranteed niche market for these machines), go ahead and throw it on to Kickstarter. Or something.
Continuing (or stumbling) along a path to using Common Lisp for stuff I consider fun, I came up with this.
As mentioned in the `README`, I need to work on making this more efficient.
Stuff I learned along the way:
- I love how I can focus on “making it work” _before_ worrying about “making it fast”
- Utilities exist for a reason. _Use them_ (I’ve decided to stick with `:rutils`)
- Don’t be afraid of using libraries. I found `:cl-log`, which is amazingly well-written and I will never use all of it, but just the basic use case of toggling levels of verbosity is good enough for me, and something that would normally be hard to do.
- Building up the system works really well. This is the first time I’ve had an experience of writing stuff that sort of _just worked_, since it felt like I was **directly translating my thoughts into code**.
- It’s easy to rapidly create and modify functions, stubs, what not, while keeping them all in view, in the same 100 or so lines of vertical space (contrast with switching between (say) multiple `.java` files)