Home
       [HN Gopher] Hofstadter on Lisp (1983)
       ___________________________________________________________________
        
       Hofstadter on Lisp (1983)
        
       Author : Eric_WVGG
       Score  : 321 points
       Date   : 2024-10-16 13:44 UTC (16 hours ago)
        
  HTML web link (gist.github.com)
  TEXT w3m dump (gist.github.com)
        
       | anthk wrote:
       | >Emacs defalias
       | 
       | On Common Lisp too, by defining defalias as a macro:
       | 
       | https://stackoverflow.com/questions/24252539/defining-aliase...
        
       | dahart wrote:
       | > Why is most AI work done in Lisp?
       | 
       | That's changed, of course, but it remained true for at least
       | another 15 or 20 years after this article was written and then
       | changed rather quickly, perhaps cemented with deep neural
       | networks and GPUs.
       | 
       | Other than running the emacs ecosystem, what else is Lisp being
       | used for commonly these days?
        
         | volltrottel wrote:
         | Running hacker news
        
         | tombert wrote:
         | Can't speak for the entire industry obviously, but at a few
         | jobs I've had [1] Clojure is used pretty liberally for network-
         | heavy stuff, largely because it's JVM and core.async is pretty
         | handy for handling concurrency.
         | 
         | I know a lot of people classify "Clojure" and "Lisp" in
         | different categories, but I'm not 100% sure why.
         | 
         | [1] Usual disclaimer: It's not hard to find my job history, I
         | don't hide it, but I politely ask that you don't post it here.
        
           | packetlost wrote:
           | > I know a lot of people classify "Clojure" and "Lisp" in
           | different categories, but I'm not 100% sure why
           | 
           | It mostly boils down to Clojure not having CONS cells. I feel
           | like this distinction is arbitrary because the interesting
           | aspect of Lisps is _not_ the fact that linked-lists are the
           | core data-structure (linked-lists _mostly_ suck on modern
           | hardware), but rather that the code itself is a tree of lists
           | that enables the code to be homoiconic.
        
             | pfdietz wrote:
             | I mean, you can have a tree of vectors also, so I don't see
             | why lists are needed for homoiconicity.
        
               | iLemming wrote:
               | No, not needed. This argumentation can go both ways; some
               | may even say, "Well, Python is 'Lispy,'" which to me is
               | obviously not. It boils down to what can you do in the
               | REPL, right?
               | https://news.ycombinator.com/item?id=41844611
        
               | vnorilo wrote:
               | In my mind Clojure is Lispy, Python is not, nor is
               | Javascript.
               | 
               | In addition to REPL and macros, I think two other Lispy
               | features are essential:
               | 
               | nil is not just the sad path poison value that makes
               | everything explode: lisp is written so that optionals
               | compose well.
               | 
               | Speaking of composing, Lisps tend to be amazing with
               | regard to composability. This is another line that cuts
               | between CL, Scheme and Clojure on one side, with Python
               | and Javascript firmly on the other side in my experience.
               | 
               | Lisps are as dynamic a languages ever go,
               | unapologetically.
        
               | iLemming wrote:
               | I just wanted to add that "dynamic" doesn't mean untyped
               | or weakly typed. Clojure is a strongly-typed dynamicly-
               | typed PL. Clojurescript compiler for example, in many
               | cases can produce safer JS code than even Typescript ever
               | could.
        
               | packetlost wrote:
               | That's mostly my point. A linked-list structure is _not_
               | the interesting part. I use the  "generic" reading of
               | list above and don't mean to imply some particular
               | implementation
        
         | iLemming wrote:
         | Some purist won't consider Clojure a "true" Lisp, but it's a
         | Lisp dialect.
         | 
         | > what else is Lisp being used for commonly these days?
         | 
         | Anything that runs on Clojure - Cisco has their cybersec
         | platform and tooling running on it; Walmart their receipt
         | system; Apple - their payments (or something, not sure);
         | Nubank's entire business runs on it; CircleCI; Embraer - I know
         | uses Clojure for pipelines, not sure about CL, in general
         | Common Lisp I think still quite used for aircraft design and
         | CAD modeling; Grammarly - use both Common Lisp and Clojure;
         | Many startups use Clojure and Clojurescript.
         | 
         | Fennel - Clojure-like language that compiles to Lua can handle
         | anything Lua-based - people build games, use it to configure
         | their Hammerspoon, AwesomeWM, MPV, Wez terminal and things-
         | alike, even Neovim - it's almost weird how we're circling back
         | - decades of arguing Emacs vs. Vim, and now getting Vim to
         | embrace Lisp.
        
           | tombert wrote:
           | When I was there, Apple used Clojure for a lot of stuff
           | involving the indexing of iTunes/Apple Music. I used it for
           | some telemetry stuff on top of the indexer as well. Not sure
           | what other teams used it for.
        
           | SSLy wrote:
           | Google Flights was built on CL, no?
        
         | casta wrote:
         | The pricing engine for Google Flights (and behind many big
         | airline websites) is written in Lisp.
        
         | mepian wrote:
         | >what else is Lisp being used for commonly these days?
         | 
         | It is being used for formal verification in the semiconductor
         | industry by companies like AMD, Arm, Intel, and IBM:
         | https://www.cs.utexas.edu/~moore/acl2/
        
         | nextos wrote:
         | > Why is most AI work done in Lisp?
         | 
         | Yann LeCun developed Lush, which is a Lisp for neural networks,
         | during the early days of deep architectures. See
         | https://yann.lecun.com/ex/downloads/index.html and
         | https://lush.sourceforge.net. Things moved to Python after a
         | brief period when Lua was also a serious contender. LeCun is
         | not pleased with Python. I can't find his comments now, but he
         | thinks Python is not an ideal solution. Hard to argue with
         | that, as its mostly a thin wrapper over C/C++/FORTRAN that
         | poses an obvious two-language problem.
        
           | sourcepluck wrote:
           | Hadn't seen that before, very interesting!
        
           | buescher wrote:
           | A friend used lush as his "secret weapon" for a while. I
           | didn't quite warm to it and now regret not paying attention.
           | It's amazing how much is packed in "batteries included."
           | 
           | Apparently it didn't make the transition to 64-bit machines
           | well? But I haven't really looked.
        
           | shawn_w wrote:
           | It's just as easy to have thin wrappers over C/etc. number
           | crunching libraries in Common Lisp as it is Python. And pure
           | CL code is typically faster than pure Python (though pypy
           | might be a different story). There's no technical reason it
           | still couldn't be dominant in AI.
           | 
           | It's a shame things took the course they did with preferred
           | languages.
        
             | mportela wrote:
             | My take is that Python won by having a complete ecosystem
             | centralizing many tools that were dispersed in different
             | languages: - Numpy/Scipy/Matplotlib enabled scientists to
             | do data analysis with Panda similar to what was available
             | in R - PySpark enabled big data scripts in Python instead
             | of Scala - PyTorch made Torch available for non-Lua users
             | 
             | Bit by bit, more people got used to doing data analysis and
             | AI research in Python. Some projects were even written for
             | Python first (e.g. Tensorflow or Keras). Eventually, Python
             | had so many high-quality packages that it became the de
             | facto for modern AI.
             | 
             | Is it the _best_ language for AI, though? I doubt. However,
             | it is good enough for most use cases.
        
         | sourcepluck wrote:
         | I think personally that Coalton and the stuff its built on is
         | crazy cool. Coalton is a little library you add to your Lisp,
         | but, to quote the third link here: "In terms of its type
         | system, Coalton's closest cousin is Haskell." So Lisp's
         | dynamism with all sorts of advanced typing.
         | 
         | QVM, a Quantum Virtual Machine https://github.com/quil-lang/qvm
         | 
         | Quilc, an "advanced optimizing compiler" for Quil
         | https://github.com/quil-lang/quilc
         | 
         | Coalton, "a statically typed functional programming language
         | built with Common Lisp." https://coalton-
         | lang.github.io/20211010-introducing-coalton/
        
         | ryukafalz wrote:
         | Guix is a Nix-like package manager and distro that is almost
         | entirely written in Guile Scheme: https://guix.gnu.org/
         | 
         | I would guess it's by far the most active Guile project.
        
         | jjtheblunt wrote:
         | Grammarly was famously using it.
         | 
         | https://www.grammarly.com/blog/engineering/running-lisp-in-p...
        
         | vindarel wrote:
         | Quantum computing and symbolic AI? But also web services, CAD
         | and 3D software, trading, designing programmable chips, big
         | data analytics...
         | 
         | present companies (that we know about):
         | https://github.com/azzamsa/awesome-lisp-companies/
        
         | tmtvl wrote:
         | > _what [...] is Lisp being used for [...] these days?_
         | 
         | I dunno, there's Nyxt, Google Flights, MediKanren, there's some
         | German HPC guys doing stuff with SBCL, Kandria,... I believe
         | there's also a HFT guy using Lisp who's here on HN. LispWorks
         | and Franz are also still trucking, so they prolly have
         | clientele.
         | 
         | There are fewer great big FLOSS Lisp projects than C or Rust,
         | but that doesn't really tell the whole story. Unfortunately
         | proprietary and internal projects are less visible.
        
         | chromaton wrote:
         | AutoCAD automation?
        
           | fuzztester wrote:
           | Yes. AutoLisp was available from the early days of AutoCAD. I
           | didn't use it much myself. I just helped some mechanical
           | engineers with it in a company where I worked, in small ways,
           | just tinkering, really. At that time I was quite junior, so I
           | didn't really grasp the power of it, so I didn't play around
           | with it much.
        
       | AnimalMuppet wrote:
       | > Every computer language has arbitrary features, and most
       | languages are in fact overloaded with them. A few, however, such
       | as Lisp and Algol, are built around a kernel that seems as
       | natural as a branch of mathematics.
       | 
       |  _Algol?_ The kernel of Algol seems as natural as a branch of
       | mathematics? Can anyone who has _used_ Algol give their opinion
       | of this statement?
        
         | andyjohnson0 wrote:
         | I did some Algol programming back in the late 80s - when it had
         | mostly been obsoleted by Pascal, Modula, and even C for what we
         | called "structured programming" back then.
         | 
         | I remember it as a likeable, economical, expressive language,
         | without significant warts, and which had clearly been
         | influential by being ahead of its time.
         | 
         | So my guess is that Hofstadter was just referring to its
         | practical elegance - rather than the more theoretical elegance
         | of Lisp.
        
           | nxobject wrote:
           | Out of curiosity: which dialect on Algol, and on what
           | platform?
        
         | gavindean90 wrote:
         | From what I've studied, Algol wasn't designed for typical
         | software development--its main purpose was to give computer
         | scientists a way to describe algorithms with a level of rigor
         | that mirrors mathematical notation.
        
         | retrac wrote:
         | C is basically Algol with curly braces and pointers. The
         | sentiment expressed there is probably equally applicable to C,
         | or maybe Pascal. Those are often held up today as a minimal
         | example in contrast to Lisp. There is a sort of sparse, warty
         | elegance to the family. Blocks, arrays, if/then, assignment,
         | while loops. What more could you need?
        
           | AnimalMuppet wrote:
           | I've used both C and Pascal. The simplicity of C comes
           | through to me (less so Pascal - the verbosity gets in the
           | way). I never thought of it as "as natural as a branch of
           | mathematics", though.
           | 
           | I mean... I guess you could think of it as having its own set
           | of self-consistent axioms, and from them you can build
           | things. It's a lot larger set of axioms than most branches of
           | mathematics, though.
           | 
           | I guess, if Hofstadter meant the same level of naturalness,
           | well, yes, C did feel pretty natural to me, so... maybe?
        
         | earthicus wrote:
         | It was discovered that the procedure mechanism of Algol 60 was
         | effectively equivalent to the lambda calulus. This insight was
         | written out in a famous paper by Peter Landin, "Correspondence
         | between ALGOL 60 and Church's Lambda-notation: part I"
         | 
         | https://dl.acm.org/doi/10.1145/363744.363749
        
         | aidenn0 wrote:
         | Hard to say without knowing which version of Algol he is
         | referring to. Algol 68 was very different from Algol 58.
         | 
         | Algol 60 was the first language with lexical scope, while Algol
         | 68 was a kitchen-sink language that (positively) influenced
         | Python and (negatively) influenced Pascal.
        
       | kjellsbells wrote:
       | Regardless of your opinion on the utility of Lisp, this is an
       | exemplary piece of writing. Crisp, engaging, informative.
       | 
       | God I miss old Scientific American. Today's SA isn't especially
       | terrible, but old SA, like old BYTE, was reliably enlightening.
        
         | taeric wrote:
         | Agreed. It saddens me how I feel I completely slept through a
         | golden age of magazines out there. With no real clue how I
         | could help support that coming back.
         | 
         | I was happy with the section in Wireframe magazines that would
         | show how to code some game mechanics every issue. Would love
         | for more stuff like that.
        
         | sgustard wrote:
         | The title of his column and book "Metamagical Themas" is an
         | anagram of Martin Gardner's previous column "Mathematical
         | Games". It's clever wordplay turtles all the way down.
        
           | madcaptenor wrote:
           | Other Hofstadter book titles with wordplay:
           | 
           | - Godel, Escher, Bach: an Eternal Golden Braid (you have
           | GEB/EGB, and I guarantee you he noticed those notes form a
           | musical triad)
           | 
           | - Metamagical Themas (anagram of Mathematical Games)
           | 
           | - Le Ton beau de Marot (I don't have my copy at hand, but
           | "ton beau" is surely a pun on "tombeau" meaning "tomb")
           | 
           | - The Mind's I (editor) (I = eye)
           | 
           | - That Mad Ache (translation of "La chamade" by Francoise
           | Sagan; "mad ache" is an anagram of "chamade")
        
             | gjm11 wrote:
             | "tombeau" _literally_ means  "tomb", but the term also
             | sometimes means "piece written as a memorial", like Ravel's
             | piano suite "Le Tombeau de Couperin". And yes, Hofstadter
             | explicitly links "ton beau" with "tombeau" (he doesn't
             | explicitly mention the "memorial" meaning, though when he
             | mentions the literal "tombeau de Marot" he is talking
             | specifically about the epitaph on it) and also with "tome
             | beau", the great book of Marot's life and work.
             | 
             | I'd find it a cleverer bit of wordplay if "le ton beau de
             | ..." itself didn't feel clumsy. Surely it would always be
             | "le beau ton de ..."?
        
               | madcaptenor wrote:
               | This was all somewhere in the back of my head but my copy
               | of this book is in my parents' basement somewhere. I'll
               | have to rescue it so I can keep it in my basement.
        
             | shrubble wrote:
             | At least one of the covers of GEB specifically had artwork
             | that shows GEB/EGB :
             | https://en.wikipedia.org/wiki/G%C3%B6del,_Escher,_Bach
        
         | goldfeld wrote:
         | The author of GEB is a phenomenal writer, an old-style
         | researcher who knew his greek, and the book for me is more
         | interesting in its commentary on literature, and psychology,
         | approaching themes of say, Foucault.
         | 
         | I don't know about the work's true impact on AI or tech
         | languages, but it's a masterpiece of criticism, analysis and
         | penmanship.
        
         | jhbadger wrote:
         | Old school SA was written assuming a basic level of scientific
         | and mathematical background. Many people reading it were
         | professional scientists and engineers who read it to learn
         | about developments in other fields than their own. Current SA
         | seems to be written at a level similar to the science coverage
         | in newspapers, written for the hypothetical "layman" who is
         | supposedly frightened of mathematics and anything technical. I
         | couldn't imagine someone like Martin Gardner or Hofstadter
         | writing in SA today.
        
         | fuzztester wrote:
         | Same with the old National Geographic magazine, before it
         | became slimmer and more ad-heavy, IIRC.
        
       | taeric wrote:
       | I do think LISP remains the major language that can encompass the
       | strange loop idea he explored in his work. I know LISP is not the
       | only homoiconic language, but it is the biggest that people know
       | how to use where the "eval" function doesn't take in a string
       | that has to be parsed.
       | 
       | I hate that people are convinced LISP == functional programming,
       | writ large. Not that I dislike functional programming, but the
       | symbolic nature of it is far more interesting to me. And it
       | amuses me to no end that I can easily make a section of code that
       | is driven by (go tag) sections, such that I can get GOTO
       | programming in it very easily.
        
         | nine_k wrote:
         | Another (properly functional) homoiconic language that enjoyed
         | mainstream adoption briefly in '00s is XSLT. Its
         | metaprogramming features were rather widely used, that is,
         | producing an XSLT from XSLT and maybe some more XML, instead of
         | hand-coding something repetitive, was rather normal.
         | 
         | The syntax was a bigger problem than Lisp's syntax, though.
         | 
         | It's not easy to produce a language with a syntax that's good
         | as daily use syntax, but is also not unwieldy as an AST. Lisp
         | is one of the few relatively successful examples.
        
           | AnimalMuppet wrote:
           | > The syntax was a bigger problem than Lisp's syntax, though.
           | 
           | Yeah. XML and S expressions are pretty close to functionally
           | equivalent. But once you've seen S expressions, XML is
           | _disgustingly_ clumsy.
        
             | nine_k wrote:
             | SGML was intended for sparse markup in mostly plaintext
             | files. From it grew HTML that is markup-heavy, and XML
             | which is often 100% markup. What made sense for rare markup
             | nodes became... suboptimal when applied in a very different
             | role.
        
               | jll29 wrote:
               | 1. GML => SGML => XML
               | 
               | 2. rm *
               | 
               | 3. JSON
               | 
               | 4. rm -rf /
        
             | pfdietz wrote:
             | "Any data can be turned into Big Data by encoding it in
             | XML."
        
             | chubot wrote:
             | They have a different model -- one is better for documents,
             | and one is better for programs/data
             | 
             | XML and HTML are attributed text, while S-expressions are
             | more like a homogeneous tree
             | 
             | If you have more text than metadata, then they are more
             | natural than S-expressions
             | 
             | e.g. The closing </p> may seem redundant, until you have
             | big paragraphs of free form text, which you generally don't
             | in programs
        
           | apex_sloth wrote:
           | Thanks for this little flashback to when I had to write XSLT
           | for apache cocoon as my student job
        
           | pmarreck wrote:
           | I don't know how many other languages use it but I've long
           | admired Elixir's approach to giving devs access to the AST
           | using its basic types in order to write macros:
           | 
           | https://hexdocs.pm/elixir/macros.html
           | 
           | It is certainly possible to implement this sort of thing in
           | other languages, I think, depending on the compilation or
           | preprocessing setup
        
         | throwaway19972 wrote:
         | Not to mention specifically with Scheme and continuation-
         | oriented programming, the line between functional and non-
         | functional programming becomes so blurry as to become nearly
         | meaningless.
        
           | brucehoult wrote:
           | Lambda: the ultimate GOTO
        
         | bbor wrote:
         | I love and relate to any impassioned plea on SWE esoterica, so
         | this seems like as good of a place as any to ask: What, in
         | practice, is this deep level of "homoiconic" or "symbolic"
         | support used for that Python's functools
         | (https://docs.python.org/3/library/functools.html) doesn't do
         | well? As someone building a completely LISPless symbolic AGI
         | (sacrilege, I know), I've always struggled with this and would
         | love any pointers the experts here have. Is it something to do
         | with Monads? I never did understand Monads...
         | 
         | To make this comment more actionable, my understanding of
         | Python's homoiconic functionality comes down to these methods,
         | more-or-less:
         | 
         | 1. Functions that apply other functions to iterables, e.g.
         | filter(), map(), and reduce(). AKA the bread-n-butter of modern
         | day JavaScript.
         | 
         | 2. Functions that wrap a group of functions and routes calls
         | accordingly, e.g. @singledispatch.
         | 
         | 3. Functions that provide more general control flow or
         | performance conveniences for other functions, e.g. @cache and
         | and partial().
         | 
         | 3. Functions that arbitrarily wrap other functions, namely
         | wraps().
         | 
         | Certainly not every language has all these defined in a
         | standard library, but none of them seem that challenging to
         | implement by hand when necessary -- in other words, they
         | basically come down to conviences for calling functions in
         | weird ways. Certainly none of these live up to the glorious
         | descriptions of homoiconic languages in essays like this one,
         | where "self-introspection" is treated as a first class concern.
         | 
         | What would a programmer in 2024 get from LISP that isn't
         | implemented above?
        
           | taeric wrote:
           | I'm basically a shill for my one decent blog post from a
           | while back. :D
           | 
           | https://taeric.github.io/CodeAsData.html
           | 
           | The key for me really is in the signature for "eval." In
           | python, as an example, eval takes in a string. So, to work
           | with the expression, it has to fully parse it with all of the
           | danger that takes in. For lisp, eval takes in a form. Still
           | dangerous to evaluate random code, mind. But you can walk the
           | code without evaluating it.
        
             | bbor wrote:
             | HackerNews sadly never fails to disappoint. Thanks for
             | taking the time to share, that was _exactly_ what I was
             | looking for! Would endorse this link for any lurkers.
             | 
             | The LISP (elisp?) syntax itself gives me a headache to
             | parse so I think I'll stay away for now, but I'll
             | definitely be thinking about how to build similar
             | functionality into my high level application code -- self
             | modification is naturally a big part of any decent AGI
             | project. At the risk of speaking the obvious, the last
             | sentence was what drove it home for me:
             | It is not just some opaque string that gets to enjoy all of
             | the benefits of your language. It is a first class list of
             | elements that you can inspect and have fun with.
             | 
             | I'm already working with LLM-centric "grammars"
             | representing sets of standpoint-specific functions
             | ("pipelines"), but so far I've only been thinking about how
             | to construct, modify, and employ them. Intelligently
             | _composing_ them feels like quite an interesting rabbit
             | hole... Especially since they mostly consist of prose in
             | minimally-symbolic wrappers, which are probably a lot
             | easier for an engineer to mentally model--human or
             | otherwise. Reminds me of the words of wonderful diehard
             | LISP-a-holic Marvin Minsky:                 The future work
             | of mind design will not be much like what we do today.
             | ...what we know as programming will change its character
             | entirely-to an activity that I envision to be more like
             | sculpturing.       To program today, we must describe
             | things very carefully because nowhere is there any margin
             | for error. But once we have modules that know how to learn,
             | we won't have to specify nearly so much-and we'll program
             | on a grander scale, relying on learning to fill in details.
             | 
             | In other words: What if the problem with Lisp this whole
             | time really _was_ the parentheses? ;)
             | 
             | source is _Logical Versus Analogical or Symbolic Versus
             | Connectionist or Neat Versus Scruffy_ : https://onlinelibra
             | ry.wiley.com/doi/full/10.1609/aimag.v12i2...
        
               | taeric wrote:
               | Glad you liked the post. I didn't do any effort to make
               | the elisp readable, so please don't let that fully put
               | you off the topic! :D
               | 
               | I keep meaning to expand on the idea. I keep not doing
               | so. I have higher hopes that I can get back to the
               | rubik's cube code. Even there, I have a hard time getting
               | going.
        
               | BoiledCabbage wrote:
               | > HackerNews sadly never fails to disappoint.
               | 
               | FYI, that means the opposite of how you used it.
               | 
               | "Never fails to disappoint" is an idiom that means a
               | person or thing consistently disappoints.
        
           | wk_end wrote:
           | The _syntax_ of Lisp is made up of the same fundamental data
           | types as you use when writing Lisp programs. `(+ 1 2 3)` is
           | _both_ a Lisp expression that evaluates to 6 and also a list
           | containing four items, the symbol `+` and the numbers 1, 2,
           | and 3.
           | 
           | In general, we can say that the Lisp language is very good at
           | manipulating the same data types that the syntax of Lisp
           | programs is made from. This makes it very easy to write Lisp
           | programs that swallow up Lisp programs _as raw syntax_ ,
           | analyze Lisp programs syntactically, and/or spit out new Lisp
           | programs _as raw syntax_.
        
       | waffletower wrote:
       | I find this article to be quaint -- remember reading it decades
       | ago and feeling more receptive to its perspective. Ironically, I
       | prefer using Clojure (though some here challenge its status as a
       | Lisp lol) to interface with Large Language Models rather than
       | Python. Clojure in particular is much better suited, for some
       | reasons that Hofstadter details, and if you can interact with an
       | LLM over a wire, you are not beholden to Python. But what we use
       | to interface to these massive digital minds we are building,
       | including the Bayesian sampling mathematics we use to plumb them,
       | may have their elegance, but they are orthogonal to the nearly
       | ineffable chaos of these deeply interconnected neural networks --
       | and it is in this chaotic interconnectedness where artificial
       | intelligence is actually engendered.
        
         | iLemming wrote:
         | > Clojure in particular is much better suited
         | 
         | Clojure in general is far better suited for manipulating data
         | than anything else (in my personal experience). It is so lovely
         | to send a request, get some data, and then interactively go
         | through that data - sorting, grouping, dicing, slicing,
         | partitioning, tranforming, etc.
         | 
         | The other way around is also true - for when you need to
         | generate a massive amount of randomized data.
        
           | troupe wrote:
           | > when you need to generate a massive amount of randomized
           | data.
           | 
           | Even faster than Clojure: Open VIM for a VS Code user and ask
           | them to exit.
        
             | iLemming wrote:
             | There's no such thing as a "VS Code user", VS Code is the
             | one that uses you, not the other way around.
             | 
             | btw. this isn't some kind of an FP joke, there's no 'fun'
             | in it, only sad truth.
        
       | InDubioProRubio wrote:
       | Lisp aNeeds Braces
        
         | paddy_m wrote:
         | > Lisp needs braces
         | 
         | You're a troll, but I'll feed you. I adapted Peter Norvig's
         | excellent lispy2.py [0] to read json. I call it JLisp [1].
         | 
         | Lispy2 is a scheme implementation, complete with macros that
         | executes on top of python. I made it read json, really just
         | replacing () with []. and defining symbols as {'symbol':
         | 'symbol_name'}. I built it because it's easier to get a webapp
         | to emit JSON then paren lisp. I also knew that building an
         | interpreter on top of lisp meant that I wouldn't back myself
         | into a corner. There is incredible power in the lisp,
         | especially the ability to transform code.
         | 
         | [0] https://norvig.com/lispy2.html
         | 
         | [1]
         | https://github.com/paddymul/buckaroo/blob/main/tests/unit/li...
         | #tests for JLisp
        
         | NateEag wrote:
         | Here, have another approach to Lisp formatting:
         | 
         | https://readable.sourceforge.io/
         | 
         | I looked into porting it to elisp a while back, but the elisp
         | reader was missing a feature or two sweet-expressions require.
         | I should see if that's still true...
        
       | dunefox wrote:
       | > I hope you enjoyed Hofstadter's idiosyncratic tour of Lisp. You
       | can find more like this re-printed in his book Metamagical
       | Themas.
       | 
       | This seems like an interesting book.
        
         | ceautery wrote:
         | It was one of my favorites back in the 1980s. It was a followup
         | to Godel Escher Bach, written in much the same style.
        
       | lopatin wrote:
       | Any Shen people in the house?
        
         | corinroyal wrote:
         | Admirer, not user. So ambitious and gorgeous. Hosted on Common
         | Lisp with full integration, so useful now. I hope more people
         | check it out. The new Shen book is awesome.
        
           | jll29 wrote:
           | links?
        
             | corinroyal wrote:
             | Here's a link to their website with the book:
             | https://shenlanguage.org/TBoS/tbos.html
        
       | susam wrote:
       | _> Attempting to take the car or cdr of nil causes (or should
       | cause) the Lisp genie to cough out an error message, just as
       | attempting to divide by zero should evoke an error message._
       | 
       | Interestingly, this is no longer the case. Modern Lisps now
       | evaluate (car nil) and (cdr nil) to nil. In the original Lisp
       | defined by John McCarthy, indeed CAR and CDR were undefined for
       | NIL. Quoting from
       | <https://dl.acm.org/doi/pdf/10.1145/367177.367199>:
       | 
       |  _> Here NIL is an atomic symbol used to terminate lists._
       | 
       |  _> car [x] is defined if and only if x is not atomic._
       | 
       |  _> cdr [x] is also defined when x is not atomic._
       | 
       | However, both Common Lisp and Emacs Lisp define (car nil) and
       | (cdr nil) to be nil. Quoting from <https://www.lispworks.com/docu
       | mentation/HyperSpec/Body/f_car...>:
       | 
       |  _> If x is a cons, car returns the car of that cons. If x is
       | nil, car returns nil._
       | 
       |  _> If x is a cons, cdr returns the cdr of that cons. If x is
       | nil, cdr returns nil._
       | 
       | Also, quoting from <https://www.gnu.org/software/emacs/manual/htm
       | l_node/elisp/Li...>:
       | 
       |  _> Function: car cons-cell ... As a special case, if cons-cell
       | is nil, this function returns nil. Therefore, any list is a valid
       | argument. An error is signaled if the argument is not a cons cell
       | or nil. _
       | 
       | _> Function: cdr cons-cell ... As a special case, if cons-cell is
       | nil, this function returns nil; therefore, any list is a valid
       | argument. An error is signaled if the argument is not a cons cell
       | or nil._
        
         | susam wrote:
         | I was curious what it is like on Maclisp. Here is a complete
         | telnet session with Lars Brinkhoff's public ITS:
         | $ telnet its.pdp10.se 10003       Trying 88.99.191.74...
         | Connected to pdp10.se.       Escape character is '^]'.
         | Connected to the KA-10 simulator MTY device, line 0
         | ^Z       TT ITS.1652. DDT.1548.       TTY 21       3. Lusers,
         | Fair Share = 99%       Welcome to ITS!            For brief
         | information, type ?       For a list of colon commands, type :?
         | and press Enter.       For the full info system, type :INFO and
         | Enter.            Happy hacking!       :LOGIN SUSAM       TT:
         | SUSAM; SUSAM MAIL - NON-EXISTENT DIRECTORY       :LISP
         | LISP 2156       Alloc? n                 *       (status
         | lispversion)       /2156       (car nil)       NIL       (cdr
         | nil)       NIL       ^Z       50107)   XCT 11   :LOGOUT
         | TT ITS 1652  Console 21 Free. 19:55:07       ^]       telnet>
         | ^D Connection closed.       $
        
           | dokyun wrote:
           | I recall reading that in early versions of Maclisp, taking
           | the CAR or CDR of NIL worked differently: Taking its CAR
           | would signal an error as you would expect, however taking its
           | CDR would return the symbol plist of NIL, as internally the
           | operation of CDR on the location of a symbol would access its
           | plist, and that's how it was commonly done before there was a
           | specific form for it (and it actually still worked that way
           | into Lisp Machine Lisp, provided you took the CDR of the
           | locative of a symbol).
           | 
           | Apparently the behaviour of the CAR and CDR of NIL being NIL
           | was from Interlisp, and it wasn't until the designers of
           | Maclisp and Interlisp met to exchange ideas that they decided
           | to adopt that behaviour (it was also ostensibly one of the
           | very few things they actually ended up agreeing on). The
           | reason they chose it was because they figured operations like
           | CADR and such would be more correct if they simply returned
           | NIL if that part of the list didn't exist rather than
           | returning an error, otherwise you had to check each cons of
           | the list every time. (If somebody can find the source for
           | this, please link it!)
        
             | pfdietz wrote:
             | But of course cadr still has to check each access, to see
             | if its of type (or cons null). So I don't see what was
             | saved.
        
               | dokyun wrote:
               | It would be considered "the right thing" to do something
               | that's so common you probably want it without asking. I
               | don't think CADR would check for NIL since it's meant to
               | be equivalent to (car (cdr x)), so if you wanted a safe
               | list operation you would have to check it like this:
               | (I'll use CADADR because it makes the issue more
               | apparent)                 (and (car x)            (cadr
               | x)            (cadar x)            (cadadr x))
               | 
               | You would have to write this every time you want to see
               | if there's a really CADADR, whereas if CAR and CDR can
               | return NIL then you can just write (cadadr x) and CADADR
               | can still be defined as (car (cdr (car (cdr x)))) and
               | have the desired behaviour.
        
         | sph wrote:
         | Sadly this is not the case with Scheme and it makes for very
         | unergonomic code, especially for a newbie like me.
         | 
         | Which is a shame, because I prefer (Guile) Scheme to Common
         | Lisp.
        
           | pfdietz wrote:
           | I'm very tied to Common Lisp, but I'm perfectly fine with the
           | idea of a lisp in which car and cdr would be undefined on
           | nil. Also, I'd be fine with a lisp in which () is not a
           | symbol. I don't think these features of Common Lisp are
           | essential or all that valuable.
        
             | sph wrote:
             | They are not essential, but they make code that operates in
             | lisp more compact and pleasant to write.
             | 
             | In Scheme my code is littered with                 (if
             | (null? lst)           ;; handle empty case here
             | ...)
             | 
             | Simply because otherwise car throws an error. This whole
             | section is often unnecessary in CL.
        
               | tmtvl wrote:
               | But you need to handle the empty case anyway otherwise
               | you process nils ad infinitum.
        
               | erik_seaberg wrote:
               | You can say                 (if lst         ...)
               | 
               | if the empty list is falsy, but Scheme eventually chose
               | to add #t and #f. Oddly #f is the only false value but #t
               | is not the only true value.
        
           | BoiledCabbage wrote:
           | > Sadly this is not the case with Scheme and it makes for
           | very unergonomic code,
           | 
           | How so? If car of nil returns nil, then how does a caller
           | distinguish between a value of nil and a container/list
           | containing nil?
           | 
           | The only way is they can check to see if it's a cons pair or
           | not? So if you have to check if it's a cons pair then you're
           | doing the same thing as in scheme right?
           | 
           | I may be missing something, but isn't it effectively the same
           | amount of work just potentially? Need to check for nil and
           | need to check if it's a pair?
        
             | susam wrote:
             | > How so? If car of nil returns nil, then how does a caller
             | distinguish between a value of nil and a container/list
             | containing nil?
             | 
             | How about this?                 CL-USER> (null nil)       T
             | CL-USER> (null '(nil))       NIL       CL-USER>
        
               | BoiledCabbage wrote:
               | I think that's my point. You still need a separate call
               | to distinguish the nil rom the list of nil case.
               | 
               | At that point, if you're making the two calls how is
               | LISP's behavior any more ergonomic than Scheme. I'm not
               | saying it's not possible, I just don't see it.
               | 
               | Can you show code between the two and how one is much
               | worse than the other?
        
         | dkarl wrote:
         | The use of car and cdr are such a surprisingly concrete
         | implementation detail in the birth of a language that was
         | designed to be mathematical. The most basic and famous
         | operators of "List Processor" were created to operate not on
         | lists but on conses, an element in a particular machine
         | representation that Lisp uses to build data structures! Not
         | only are conses not always interpreted as lists, but a very
         | very important list, the base case for recursive functions on
         | lists, is not represented by a cons.
         | 
         | Sixty years later, most Lisp programs are still full of
         | operations on conses. A more accurate name for the language
         | would be "Cons Processor!" It's a reminder that Lisp was born
         | in an era when a language and its implementation had to fit
         | hand in glove. I think that makes the achievement of grounding
         | a computer language in mathematical logic all the more
         | remarkable.
        
           | fuzztester wrote:
           | maybe related to the need to _cons_ erve CPU registers in
           | machines of the time?
           | 
           | https://en.m.wikipedia.org/wiki/CAR_and_CDR
           | 
           | In any case, _AST_ ute _observation_
           | 
           | er, ASTute _;_ )
        
         | lisper wrote:
         | > Modern Lisps now evaluate (car nil) and (cdr nil) to nil.
         | 
         | Scheme doesn't. Taking the CAR or CDR of nil is an error.
        
           | anthk wrote:
           | Elisp and CL do.
        
           | susam wrote:
           | Does Scheme even have NIL in the sense that other Lisps like
           | CL or Elisp have? I mean in Common Lisp, we have:
           | CL-USER> (symbolp nil)       T       CL-USER> (atom nil)
           | T       CL-USER> (listp nil)       T
           | 
           | Similar results in Emacs Lisp. But in MIT Scheme, we get:
           | 1 ]=> nil            ;Unbound variable: nil
           | 
           | Of course, we can use () or (define nil ()) to illustrate
           | your point. For example:                 1 ]=> (car ())
           | ;The object (), passed as the first argument to car, is not
           | the correct type.
           | 
           | But when I said NIL earlier, I really meant the symbol NIL
           | that evaluates to NIL and is both a LIST and ATOM. But
           | otherwise, yes, I understand your point and agree with it.
        
             | dokyun wrote:
             | I don't believe so, standardly. Guile scheme added the
             | value `#nil' which is equivalent to NIL and distinct from
             | #f and the empty list, but this was done in order to
             | support Emacs Lisp.
        
             | lisper wrote:
             | > Does Scheme even have NIL in the sense that other Lisps
             | like CL or Elisp have?
             | 
             | No. It has an empty list, which is a singleton atomic value
             | whose type is not shared with any other object, and it has
             | a boolean false value, which is distinct from the empty
             | list. A user can create a symbol named NIL, but that symbol
             | has no characteristics that distinguish it from any other
             | symbol. You can, of course, bind NIL to either the empty
             | list or boolean false (or any other value) but it can only
             | have one value at a time (per thread).
        
         | lisper wrote:
         | There really should be two different kinds of cons cells, one
         | for "proper" linked lists and another for general purpose
         | consing. The difference is that the cdr of the first kind of
         | cons cell (I'll call it a PL-cons) can only be NIL or another
         | PL-cons, not anything else. This would eliminate vast
         | categories of bugs. It would also make the predicate for
         | determining is something was a proper list run in constant time
         | rather than O(n). (There would still be edge cases with
         | circular lists, but those are much less common than non-proper
         | lists.)
        
       | oaktowner wrote:
       | I just love his writing so much -- he captures what I felt when I
       | discovered Lisp. As a kid learning programming in the 80s, I had
       | already done some BASIC, Fortran, Pascal and COBOL in high school
       | and early college. There were differences, of course, but they
       | had some fundamental commonality.
       | 
       | At UC Berkeley, however, the first computer science class was
       | taught in Scheme (a dialect of Lisp)...and it absolutely blew me
       | away. Hofstadter is right: it feels the closest to math
       | (reminding me a _ton_ of my math theory classes). It was the
       | first _beautiful_ language I discovered.
       | 
       | (edit: I forgot to paste in the quote I loved!)
       | 
       | "...Lisp and Algol, are built around a kernel that seems as
       | natural as a branch of mathematics. The kernel of Lisp has a
       | crystalline purity that not only appeals to the esthetic sense,
       | but also makes Lisp a far more flexible language than most
       | others."
        
         | Jeff_Brown wrote:
         | Have you tried Haskell? It feels much closer to math to me.
         | Definitions, not procedures. It even _looks_ like math.
        
           | oaktowner wrote:
           | No! After about 10 years of writing software professionally,
           | I moved over to product management, and my time spent coding
           | decreased drastically (in the last 15 years, only some Python
           | to show my kids a thing or two).
           | 
           | But I'd love to try! Maybe I'll take an online class for fun.
        
             | Jeff_Brown wrote:
             | I can't recommend it highly enough. You're already familiar
             | with laziness from Lisp, but purity is another head-trip.
             | It made me a better programmer in any language, and even a
             | better software architect before I've written a line of
             | code.
             | 
             | And algebraic data types make it possible to make your code
             | conform to reality in ways that classes can't. Once you're
             | exposed to them, it's very much like learning about
             | addition after having been able to multiply for your whole
             | life. (In fact that's more than a metaphor -- it's what's
             | happening, in a category theoretic sense.)
             | 
             | Haskell has other cool stuff too -- lenses, effect systems,
             | recursion schemes, searching for functions based on their
             | type signatures, really it's a very long list -- but I
             | think laziness, purity and ADTs are the ones that really
             | changed my brain for the better.
        
               | sourcepluck wrote:
               | Have you tried Coalton? It's a Common Lisp library that
               | adds Haskell-esque (or near-Haskell) type wonders, and
               | which smoothly interoperates with your Common Lisp code.
               | 
               | Your comment is great though, consider me convinced. I've
               | done a bit of messing with Lisp, but really would like to
               | try write something in Haskell, or slog through a book or
               | two, some day.
        
               | chamomeal wrote:
               | Damn that was a really good pitch. I think I'm too dumb
               | to learn Haskell though lol. I'm struggling enough with
               | immutability in clojure!!
        
           | tightbookkeeper wrote:
           | Personal anecdote: I got a lot more out of lisp that stuck
           | with me than Haskell. Occasionally I say "oh this is a monad"
           | or think about a type signature, but that's about it.
        
         | nxobject wrote:
         | At the risk of diverging off from the original post, I also
         | think that calling it "math" might make things a bit murky (and
         | this is coming from someone who wanted to be algebraic
         | topologist!)
         | 
         | It _is_ an elegant and minimal expression of a style of
         | programming that is ubiquitous among dynamically-typed,
         | garbage-collected languages. And it's a "theory" in the sense
         | that it seems complete, and that you can think of ways to solve
         | problems into Scheme and translate that into other dynamically-
         | typed languages and still end with an elegant solution.
         | Emphasis on the elegant (since minimal, wart-free, consistent
         | and orthogonal, etc.).
         | 
         | Scheme was a simplification and a "cleaning up" compared to
         | conventional Lisps of the time (lexical scoping, single shared
         | namespace for functions and variables etc.)
        
       | eigenhombre wrote:
       | I loved Hofstadter's writing on Lisp in Metamagical Themas and
       | adapted the code in the last article of the series to Clojure for
       | a study group at work, written up here[1].
       | 
       | [1] http://johnj.com/posts/oodles/
       | 
       | edit: clarification
        
         | silcoon wrote:
         | Nice, I wonder if there was a translation on a modern Lisp.
        
           | abecedarius wrote:
           | https://github.com/darius/cant/blob/master/examples/text/ood.
           | .. though modern is a matter of fashion.
        
       | susam wrote:
       | _> In a testament to the timelessness of Lisp, you can still run
       | all the examples below in emacs if you install these aliases:_
       | 
       |  _> (defalias  'plus #'+)_
       | 
       |  _> (defalias  'quotient #'/)_
       | 
       |  _> (defalias  'times #'*)*
       | 
       | _> (defalias 'difference #'-)*
       | 
       | Looks like we also need a defmacro for def that is used much
       | further in the article:
       | 
       |  _> > (def rac (lambda (lyst) (car (reverse lyst))))_
       | 
       | I mean the above example fails in Emacs:                 ELISP>
       | (def rac (lambda (lyst) (car (reverse lyst))))       *** Eval
       | error ***  Symbol's function definition is void: def
       | 
       | If we want the above example to work, we need to define def like
       | this:                 ELISP> (defmacro def (name lambda-def)
       | `(defalias ',name ,lambda-def))       def
       | 
       | Now the previous example, as presented in the article, works
       | fine:                 ELISP> (def rac (lambda (lyst) (car
       | (reverse lyst))))       rac       ELISP> (rac '(your brains))
       | brains
        
       | activitypea wrote:
       | I remember reading GEB and being shocked that he never mentions
       | Lisp. He _does_ wade into CompSci topics, but it's something
       | half-hearted about how compilers are programs that read and
       | generate programs. This really should've been integrated into a
       | revised edition of the book.
        
         | lisper wrote:
         | Huh? He mentions Lisp all over the place. Check the index.
        
         | silcoon wrote:
         | Give it another go! _The Anatomy of LISP_ is the first entry in
         | the bibliography.
        
         | baruchthescribe wrote:
         | Nonsense.
         | 
         | "One of the most important and fascinating of all computer
         | languages is LISP (standing for "List Processing"), which was
         | invented by John McCarthy around the time Algol was invented.
         | Subsequently, LISP has enjoyed great popularity with workers in
         | Artificial Intelligence."
        
       | susam wrote:
       | In case anyone else is confused by what the functions named
       | "oval" and "snot" mean in the following example:
       | > (cond ((eq (oval pi) pie) (oval (snot pie pi)))       (t (eval
       | (snoc (rac pi) pi))))
       | 
       | I realised after a few seconds that they are meant to be "eval"
       | and "snoc" instead. The above code should be written as the
       | following instead:                 (cond ((eq (eval pi) pie)
       | (eval (snoc pie pi)))             (t (eval (snoc (rac pi) pi))))
       | 
       | This article has been a fascinating read, by the way. Kudos to
       | the maintainer of the Gist post. I am also sharing these
       | corrections as comments on the Gist post.
       | 
       | EDIT #1: Downloaded a copy of the original Scientific American
       | article from https://www.jstor.org/stable/24968822 and confirmed
       | that indeed the functions "oval" and "snot" are misspellings of
       | "eval" and "snoc".
       | 
       | EDIT #2: Fixed typo in this comment highlighted by @fuzztester
       | below.
        
         | hinkley wrote:
         | OCR maybe?
        
         | fuzztester wrote:
         | >confirmed that indeed the functions "oval" and "snot" are
         | misspellings of "eval" and "snot".
         | 
         | Correction of your correction:
         | 
         | confirmed that indeed the functions "oval" and "snot" are
         | misspellings of "eval" and " _snoc_ ".
         | 
         | And I guess snoc is cons reversed and rac is car reversed.
        
           | susam wrote:
           | > Correction of your correction
           | 
           | Thanks! Fixed.
           | 
           | > And I guess snoc is cons reversed and rac is car reversed.
           | 
           | Indeed! That's exactly how those functions are introduced in
           | the article. Quoting from the article:
           | 
           |  _> The functions rdc and snoc are analogous to cdr and cons,
           | only backwards._
        
       | kevindamm wrote:
       | This article, and the two companion articles it mentions, can be
       | found in the book "Metamagical Themas" [0] in chapters 17-19, as
       | well as all of his other articles that appeared in this series of
       | Scientific American.
       | 
       | [0]:
       | https://www.goodreads.com/book/show/181239.Metamagical_Thema...
       | 
       | (the book's title is the article series, which originated as an
       | anagram of the article series that Martin Gardner authored,
       | "Mathematical Games," also published in Scientific American and
       | which Hofstadter then took over)
        
         | antitoi wrote:
         | I love this book. Highly recommended for all lovers of Godel
         | Escher Bach (his classic).
        
       | analog31 wrote:
       | I read that article when it came out, as my parents subscribed to
       | Scientific American. Even though I had learned BASIC and Pascal,
       | the concepts in the article were just way over my head. Also, I
       | had no access (that I was aware of at least) to a machine where I
       | could try my hand at Lisp programming. Alas, I wish I had taken
       | it more seriously.
       | 
       | At least Hofstadter was successful at getting me interested in
       | math beyond high school.
        
       | bsder wrote:
       | This article simply reinforces that the primary problem with the
       | popularity of Lisp was people _explaining Lisp_.
       | 
       | This article, like every other Lisp article, tells pre-teen me
       | _nothing that he could use_. Nobody ever demonstrated how much
       | easier task X is in Lisp over asm /C/Pascal/etc.
       | 
       | By contrast, current me could have told pre-teen me "Hey, that
       | spell checker that took you 7 months to write in assembly? Yeah,
       | it's damn near trivial in Lisp on a microcomputer with bank
       | switched memory that nobody every knew how to utilize (it makes
       | garbage collection completely deterministic even on a woefully
       | underpowered CPU). Watch."
       | 
       | I want to weep over the time I wasted doing programming with the
       | equivalent of tweezers, rice grains and glue because every Lisp
       | article and textbook repeated the same worn out lists, recursion
       | and AI crap without ever demonstrating how to do anything
       | _useful_.
        
         | lispm wrote:
         | Practical Common Lisp https://gigamonkeys.com/book/
        
           | bsder wrote:
           | Didn't exist back then. Likewise SICP first edition was 1996.
           | 
           | I did have a copy of "LISP: A Gentle Introduction to Symbolic
           | Computation" by Touretzky in 1986. It wasn't really that much
           | better than any of the articles. It never explained _why_
           | using Lisp would be so much easier than anything else even
           | for simple programming tasks.
           | 
           | Had some of the Lisp hackers deigned to do stuff on the
           | piddly little micros and _write it up_ , things would look a
           | whole lot different today.
           | 
           | Maybe there was a magazine somewhere doing cool stuff with
           | Lisp on micros in the 1980-1988 time frame, but I never found
           | it.
        
             | keithwinstein wrote:
             | The first edition of SICP came out in the fall of 1984 (a
             | year after these Hofstadter columns). This fall is the 40th
             | anniversary!
        
               | bsder wrote:
               | I stand corrected on that. Thanks.
        
         | troupe wrote:
         | Common Lisp: A Gentle Introduction to Symbolic Computation
         | might be useful for the context you are describing.
         | https://www.cs.cmu.edu/~dst/LispBook/
        
         | abecedarius wrote:
         | Hofstadter's followup article had a more interesting example.
         | 
         | When I first got a Byte magazine as a pre-teen, one of the
         | articles was Lisp code for symbolic differentiation and
         | algebraic simplification. I _really_ couldn 't follow it but
         | felt there was something intriguing there. Certainly it
         | wouldn't have been easier in Basic.
         | 
         | (Byte September 1981, AI theme issue. Later I was able to tell
         | the code was not so hot...)
         | 
         | I didn't really get into Lisp until the late 80s with XLisp on
         | a PC, and SICP. Worth the wait!
        
       | timonoko wrote:
       | Maclisp goodness:                 (compress (reverse (explode
       | x)))
       | 
       | Elisp much improved:                 (defun explode (x)
       | (if (symbolp x) (setq x (symbol-name x)))         (string-to-list
       | x))       (defun compress (x) (concat x))
        
         | UniverseHacker wrote:
         | (upgrade (mail (change (trash (fix (break (use (buy it))))))))
        
         | timonoko wrote:
         | I was wrong: It was "implode" in Maclisp.
         | (compress (reverse (explode 'ABC)))       ;COMPRESS UNDEFINED
         | FUNCTION OBJECT            (implode (reverse (explode 'ABC)))
         | CBA
         | 
         | The point being that I never learn any fancy string-processing
         | commands. I just implement explode and compress.
        
       | smrq wrote:
       | I certainly know the Lisp information in this article already,
       | but it's still a fun read. Hofstadter just has a charming way
       | with words.
       | 
       | I found this bit extra amusing:
       | 
       | >It would be nice as well as useful if we could create an inverse
       | operation to readers-digest-condensed-version called rejoyce
       | that, given any two words, would create a novel beginning and
       | ending with them, respectively - and such that James Joyce would
       | have written it (had he thought of it). Thus execution of the
       | Lisp statement (rejoyce 'Stately 'Yes) would result in the Lisp
       | genie generating from scratch the entire novel Ulysses. Writing
       | this function is left as an exercise for the reader.
       | 
       | It took a while, but we got there. I don't think 2024's AI is
       | quite what he had in mind in 1983, but you have to admit that
       | reproducing text given a little seeding is a task that quite
       | suits the AI of today.
        
       ___________________________________________________________________
       (page generated 2024-10-17 06:00 UTC)