Lisp & Smalltalk

I was wondering if other Twit users use these two languages? These are my favorites and I know I’ve heard Leo say he programs in Lisp. I also love Clojure and Clojurescript, which are Lisps as well and have the entire Java ecosystem at their disposal. Reply in this thread if you like Lisp and Smalltalk and the things you do with them. Would love to see this conversation grow to be huge…

Sam

Well, at the risk of being off topic, as a coder I have no experience with functional languages like Lisp, and I don’t really understand the appeal. I have used the functional (aka Lambda) additions to Java, and I find them frequently a distraction and less understandable than simple loops and ifs. (This could just be a consequence of how they were added, after the fact, to an otherwise traditional programming language.)

I tried to watch this video on the topic, which will appeal to @staypufd, but just made me further think it is kinda culty (sorry.)

1 Like

Thanks for sharing the link.

I’ve used both Smalltalk and Lisp. Smalltalk is fascinating - the original object oriented language. If you want to understand Alan Kay’s original OOP it’s fantastic. Great as long as you don’t mind living in the Smalltalk environment, which is pretty dated these days.

Common Lisp, on the other hand, is extraordinarily rich and everything I’m looking for in a language. I’m practicing with it now in order to be ready for the Advent of Code in a month. Here’s my code so far (through day 7 of day 2015): GitHub - leolaporte/aoc-cl - my Racket scheme code from last year is here.

I don’t actually code anything useful.

1 Like

Yes, I’m a longtime user of both Lisp and Smalltalk.

Smalltalk was the first object-oriented language that I learned and one that I really enjoyed using to write prototype code, mostly due to the ability to modify code on the fly while it was still running. It’s not a language that I use anymore but I will forever be fond of it.

I learned Lisp for customising GNU-Emacs, which I started using in the 1980s and continue to use to this day. The keyboard shortcuts for Emacs are hardwired into my fingers’ muscle-memory so it remains the text editor that I am most effective with.

As part of my college degree, I wrote a thesis on object oriented programming and Smalltalk, which was “new” and almost unknown at the time 1985.

I learnt the basics of it, but didn’t have any hardware to run it on, to get a real feel for it. A few years later, I did some Smalltalk programming on the Amiga.

I grew up on functional programming, it was a big change to switch to OOPs, when they became popular. Luckily, my college work on Smalltalk made the transition a bit easier.

I am self-taught. I started on Vic-20 Microsoft BASIC 2.0 before I even had a computer. (Writing programs on paper while reading a copy of the owners manual I got in advance of the computer because I was still saving the $400Cdn as a young teenager.) I self-taught myself 6502 assembly next from Jim Butterfield’s great book on the topic. I moved to the C64 and then eventually to the Amiga. I went to university, and learned a lot of different languages, from FORTRAN, COBOL, APL, PL/1, Modula-2, REXX (and then ARexx for the Amiga) and C/C++. Once I learned C, it became my main programming language for many years. I learned Java at an official Sun event, prior to Java becoming generally available, and the switch to object oriented programming was comfortable as I was already trying to build code that way in C.

I have a friend who really fell in love with the D language, but unfortunately the library of code doesn’t support his interests well, so he’s had to abandon it for C++. I also like Lua/Wren/Python for embedding, but I prefer a strongly typed and compiled language for “serious” code.

All the above to say, at no point was I ever introduced to anything like Smalltalk or Lisp. I did have a brief encounter with Fourth, but it was on the C64 and wasn’t very friendly. At this point, I am too comfortable in Java to want to switch to anything else, although I may give Rust a try to see if I can use it in replacement for C in the future.

EDIT: just after I posed this, I saw the #clojure tag on TWiT.social, so in an effort to bring something meaningful to the discussion, there’s this: #clojure - TWiT.social

Here’s the definitive piece on why developing in Lisp and Smalltalk is so different. It’s about how you develop. In Lisp and Smalltalk you program…

by starting the language engine and talking to it, teaching it how to be your program interactively, by changing it while it runs.

https://mikelevins.github.io/posts/2020-12-18-repl-driven/

@Leo How does such an environment work if you’re not planning on giving your source away? (i.e. close source?) I suspect if there is no way to close down the source, that commercial software developers will shun it, and that could explain why it remains less prevalent that compiled source alternatives.

Not at all. Lisp, at least, can be compiled into an .exe like any other language. Smalltalk usually gets distributed as an image but that doesn’t mean the souce is necessarily visible. It’s kind of desirable that it is, though, so the end user can modify it to suit.

I’m a big Lisp fan, though the lisp I’ve been using most of the time lately is Clojure and I haven’t touched CL or Scheme in a while.

I’m going to have to disagree that loops are clearer than functional sequence operations (map, reduce, filter) in most cases. I should note I have not used them in Java, so I can’t say whether something about how it fits into that language makes it messy. What probably doesn’t end up very clean is people extracting more complex loop bodies into anonymous functions, and I could imagine that happening in an existing Java codebase.

Used well, sequence functions provide more information about what the code is doing at a glance than loops do. If you see map for example, you know you can expect the output to have the same length and each element to be transformed. You can expect it won’t terminate without touching every element. You should expect that the transformation of each element doesn’t depend on the value of any other element (code that does otherwise is pathological). A loop tells you none of those things.

1 Like

Well, I borrowed this example from a website, you be the judge how you like it:

// Applying 12% VAT on each purchase
// Old way:
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
double total = 0;
for (Integer cost : costBeforeTax)
{
  double price = cost + .12*cost;
  total = total + price;
}
System.out.println("Total : " + total);

// New way:
List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);
double bill = costBeforeTax.stream()
  .map((cost) -> cost + .12*cost)
  .reduce((sum, cost) -> sum + cost)
  .get();
System.out.println("Total : " + bill);


Output
Total : 1680.0
Total : 1680.0

I see an additional complication here: these operations don’t work on Java’s built-in collection/sequence types but streams. That + and * aren’t functions also complicates it.

In Clojure:

(def cost-before-tax [100, 200, 300, 400, 500])

(defn bill [items]
  (->> items
       (map (partial * 1.12))
       (reduce +)))

A friend just referred to this. Some of you may be interested in knowing about it.