Now that I'm out of the corporate tyranny and have my own company, I use lisp for everything. There's certain satisfaction in writing config files and persisting data directly in s-expressions. Any json requirements are triggered by exports to foreign systems.
Which Lisp, out of interest?
That JSON prohibits trailing commata makes it an absolute pain to work with in practice.<p>I also like how in Haskell:<p><pre><code> something =
{ element
, element1
, element2
, element3
}
</code></pre>
Is an actually idiomatic way to deal with the lack of trailing commata.
I did something like that in C++ circa 1998, before seeing it anywhere else:<p><pre><code> MyClass::MyClass(foo bar, int arg1, int arg2)
: Base(bar)
, member1(arg1)
, member2(arg2)
{
}</code></pre>
For folks that want all of this plus macros (and a lot of other great things), check out Elixir.
One way I find traditional Lisp style more painful for functional code than Ruby is that fully functional-style Lisp pushes me to read and write code <i>the opposite way</i> from how I think about it. In the author's example:<p><pre><code> orders
.select { |o| o.placed_at > 1.week.ago }
.group_by(&:customer_id)
.transform_values { |group| group.sum(&:total) }
</code></pre>
the equivalent Lisp code would either be written in imperative style as multiple statements that each write to a temporary variable or (let) binding, or would look like this:<p><pre><code> (reduce #'+
(map (lambda (o) (getf o 'total))
; this group_by replacement function
; might be written as hash-table code
(my-group-by 'customer-id
(remove-if-not
(lambda (o)
(>
(getf o 'placed-at)
(- (my-now) (* 60 60 24 7))))
orders))))
</code></pre>
where I now have to read from bottom to top to understand the order of operations on the `orders` record set, even though when I wrote the code earlier, I "logically" thought from first operation to last when deciding which high-level operations to use in which order.<p>Other imperative languages that support functional code either make you do things imperatively to get the "logical" ordering of functional operations like I feel Lisp pushes you to do, or they do something like Ruby where things can be chained left to right in a "single" statement even for operations that were not thought of ahead of time by the creators of opaque data structures you later need to operate on. (Everything is a user-extensible object like Ruby, unified function call syntax in D, extension methods in C#, or pipelines of structured objects in PowerShell.)
Threading macros are nice, though, right?<p><a href="https://docs.racket-lang.org/threading/introduction.html" rel="nofollow">https://docs.racket-lang.org/threading/introduction.html</a>
They're nice, but they're not the same thing.<p>The threading macros are (as I understand it) pure sugar.<p>Turning (-> (gather my-list) uppercase-list sort) into (sort (uppercase-list (gather my-list))).<p>In contrast to, say, Java (I can't speak to the code above):<p><pre><code> List<Things> things = thingIds.stream()
.map(model::findThing)
.filter(Objects::nonNull)
.toList();
</code></pre>
These are streamed. This is pretty much a pipe structure, whereas the threading macros will create a lot of temporary copies of the data (I don't know if that's a universal truth). That is, if you're processing a 1000 items, say `gather` returns a 1000 items, that 1000 item list is passed to `uppercase-list` which return a new 1000 item list to feed to `sort` which returns another 1000 item list (assuming none of these are destructive).<p>I wish CL had something like the Java streams (maybe it does).
I feel languages should just have some kind of sugar or operator for this, in fact in Ocaml the |> operator exists where<p><pre><code> <exp> |> <exp2>
<exp2>(<exp>)
</code></pre>
Are just one and the same<p>For a variadic language you'd need something more involved though. But some kind of syntax can probably be invented in some language.
It's common to write the thrush combinator as a lisp macro. Clojure ships ->, ->>, as->, some->, some->>, cond->, and cond->> out of the box. You can find similar macros for CL[0], Racket[1], and a scheme SRFI[2]. Writing them is a fun exercise in your lisp of choice if you don't have a library available.<p>[0] <a href="https://github.com/dtenny/clj-arrows" rel="nofollow">https://github.com/dtenny/clj-arrows</a><p>[1] <a href="https://docs.racket-lang.org/threading/index.html" rel="nofollow">https://docs.racket-lang.org/threading/index.html</a><p>[2] <a href="https://srfi.schemers.org/srfi-197/srfi-197.html" rel="nofollow">https://srfi.schemers.org/srfi-197/srfi-197.html</a>
> He’s described Ruby’s design as starting from a simple Lisp, stripping out macros and s-expressions<p>Put the macros back! It would be so cool!
I love Ruby, use it for most of my projects that don't require performance.<p>Nothing I would love more than a Ruby with a Common-Lisp like compiler and runtime. Unboxed types, native compilation, partial compilation, live image (Ruby has this but "faster Rubies" like Crystal don't), etc...
I came close to adopting Scala, many parallels to Ruby with vastly better performance.<p>I'm Ruby or Lean 4.
... or just use Common Lisp.
That is actually Lisp influence on Smalltalk, and Perl, that eventually influenced Ruby.
From the article<p>> Matz has said as much. He’s described Ruby’s design as starting from a simple Lisp, stripping out macros and s-expressions, then adding an object system, blocks, and Smalltalk-style methods. The features most Rubyists fall in love with aren’t the object-oriented ones. They’re the functional ones, dressed in friendlier clothes.
Totalle agree, I just googled it:
"Yukihiro 'Matz' Matsumoto heavily credits Smalltalk as the deepest structural inspiration behind Ruby’s object model. He combined Smalltalk’s beautiful object-oriented architecture and message-passing system with features from other languages to create a tool designed primarily for developer happiness."
Including the closures and collection operations.
No, its actual influence from Lisp-family languages (including Scheme). Yes, Lisp also influenced Perl and Smalltalk, but Matz was not ignorant of Lisp with the only influence om Ruby from Lisp being indirect through those other languages.
What have the Lisps ever done for us?<p><a href="https://www.youtube.com/watch?v=Qc7HmhrgTuQ" rel="nofollow">https://www.youtube.com/watch?v=Qc7HmhrgTuQ</a>
[dead]