[HN Gopher] Common Data Structures in Common Lisp
___________________________________________________________________
Common Data Structures in Common Lisp
Author : djha-skin
Score : 44 points
Date : 2024-05-18 23:10 UTC (23 hours ago)
(HTM) web link (blog.djhaskin.com)
(TXT) w3m dump (blog.djhaskin.com)
| nomilk wrote:
| I started learning common lisp this week. Instead of jumping
| straight into code/syntax as I would with other languages, I
| spent the first 3 days reading about (and trying to understand)
| homoiconicity.
|
| The tl;dr is it's metaprogramming made extremely convenient. In
| other languages metaprogramming might involve regex to parse
| string representations of code, perhaps string interpolation, and
| eventually pass strings to eval() or similar. But since lisp code
| _is_ its own data structure (not just a string as in other
| languages), the ways of interacting with and altering lisp code
| programatically are every bit as robust as the methods for
| altering any other data structure (like a list or array).
|
| For obvious reasons, I'm proceeding with caution, as some
| practices are best exercised judiciously or infrequently (or
| never e.g. ruby continuations).
|
| But my early thoughts are that now that I know of this concept it
| seems odd that it's not feature of every programming language. I
| guess languages can still be highly productive without
| metaprogramming as a first class citizen. And, funnily, it's
| probably a good thing if tools like metaprogramming (and
| properties like homoiconicity) are a not obvious first choices
| for solving problems.
| skydhash wrote:
| Almost every time I try to reach to meta-programming, on second
| thought, I found out that writing a method was the simpler way.
| I'm not a LISP expert, but IMO, if you're not building a
| library, meta-programming is an exotic paradigm. And that's
| because you're defining a new language, not adding new words in
| a dictionary.
|
| I think it's quite nice if you're building tooling though. Like
| creating a web framework to write web apps, or translating
| business queries to SQL.
|
| Writing imperative code always felt like transporting buckets
| of water. But CL (and other functional languages) feels like
| building a pipe system. Much more knowledge required upfront,
| but getting nicer the further you progress.
|
| ADDED:
|
| That's why there are so many frameworks, especially in the web
| dev world. It's nice to have someone carry the buckets to your
| room, even though you need to get it inside. The trouble starts
| when you want water somewhere not serviced. You have to figure
| the service routes to take it of at the most convenient place.
| citizen_friend wrote:
| For typical projects you just need a handful. In other
| programming languages that means code generation or macro
| hell. So it is nice that it's built into the language to do
| it properly, even if you only use it for those few things.
| lispm wrote:
| Let's imagine we want to program some kind of state machine
| machinery.
|
| We can ask ourselves questions: what should it do? how should
| it work? what kind of features would it need to provide? From
| what parts would we like to build it? How can we integrate it
| into the programming language we use? How can we make it
| fast? How can we deal with errors?
|
| There is a question we haven't been asking yet: how do we
| want to write them down? What would be a compact notation,
| verifiable for a state machine?
|
| That's something which one can ask very early in Lisp: How
| should my code look like? How can I make sure I understand
| the state machine itself (not the low-level programming)
| months, years later and make changes to it?
|
| One way to answer that would be to add a syntax extension for
| state machines to Lisp. That would be embedded into the
| language. One can experiment with that, without the need to
| write too complex scanner&parser combinations. Just write the
| state machine as a list of state descriptions. A macro could
| transform it at compile-time into (efficient) low-level
| operations.
| pjlegato wrote:
| If you like CL, try Clojure -- all the Lispy goodness, but with
| access to modern, industrial-use libraries.
|
| Common Lisp is largely abandonware at this point -- e.g.
| there's no standard way to open a TCP socket!
| djha-skin wrote:
| I actually switched from Clojure to CL.
|
| I switched because I was making command line tools and
| clojure's startup time is abysmal. Babashka doesn't have all
| the libraries and GraalVM's native image requires herculean
| effort to work even a little bit and spits out monstrously
| huge binaries.
|
| Common Lisp is actually a lot more popular than I thought it
| was. I think perhaps it doesn't look that way, but it's very
| strong I assure you. Join us on the lisp Discord!
|
| It is possible to create relatively small binaries out of the
| box with nearly instant startup time. There's plenty of
| libraries and a strong community. There's also a great number
| of implementations.
|
| A lot of the things that are not standardized in the standard
| have been standardized via implementation agreement and
| libraries abstracting away different implementation
| differences, such as cffi and bordeaux-threads. I defy
| closure to have anything nearly as feature complete for
| parallelization as parallels, blackbird, and CL-async.
| Speaking of which, the C FFI story is strong enough with lisp
| that any major missing library or language feature usually
| has a wrapping list Library around that feature written in C.
| While it's not standard, all the major implementations have
| adopted gray streams and people use flexi streams to open
| sockets. It's the same kind of du jour standard that Clojure
| relies on.
|
| The standard is flexible enough to have several different
| implementations on several different platforms. If I need to
| interface with jvm languages, I can use armed bear common
| lisp. If I need just a really strong implementation that
| works in most situations I can use CCL or sbcl. If I need to
| integrate heavily with C or C++ code I can use ecl or clasp.
|
| It is clunkier because it takes the view that agreement
| between programmers is more important than clean syntax. The
| standard was created to unite the different lisp
| implementations instead of divide them. I value this view.
| lispm wrote:
| https://usocket.common-lisp.dev/
| hcarvalhoalves wrote:
| I've been working with Clojure for the past 8 years, and
| while I can vouch for it, I wouldn't say it has _all_ the
| Lispy goodness of CL:
|
| - it lacks a robust debugger (where you can step, redefine,
| continue...)
|
| - it uses the GC of the host VM
|
| - can't save interpreter images
|
| - is designed to be a hosted language, meaning many
| implementation details are left to the host VM (JVM or JS)
|
| - type checking
|
| - performance
|
| Also, wouldn't call CL abandonware, since it's a standardized
| language. Abandonware by my definition is all the Python 2 or
| JS code that you can't run on a current implementation.
| phoe-krk wrote:
| There is - USOCKET:SOCKET-CONNECT.
|
| If we end up in petty and unproductive nitpicking like that,
| then there's no standard way to open a TCP socket in Clojure
| either. Mostly because Clojure, unlike Common Lisp, does not
| have a standard to talk of.
| phoe-krk wrote:
| It's weird to see singly linked lists, adjustable arrays, and
| hash tables implemented in Common Lisp in such a post. All three
| of these data structures are _always_ already implemented in
| Lisp, as mandated by the standard.
___________________________________________________________________
(page generated 2024-05-19 23:02 UTC)