[HN Gopher] Common Lisp's block / return-from and unwind-protect
___________________________________________________________________
Common Lisp's block / return-from and unwind-protect
Author : bshanks
Score : 105 points
Date : 2024-01-21 01:37 UTC (21 hours ago)
(HTM) web link (axisofeval.blogspot.com)
(TXT) w3m dump (axisofeval.blogspot.com)
| wait_a_minute wrote:
| Gah, another Lisp post to tempt me to add yet another mini
| project to my plate...I always am curious about trying more Lisp
| because I keep seeing commentary about how powerful it is to
| actually build applications once you get moving on building
| things.
|
| Anyone here have any recent practical experience in this
| direction who would confirm this in Lisp vs in other programming
| languages? Does effort in Lisp really compound/produce great code
| and great applications that much faster than other languages?
| (For web development primarily)
| rokkitmensch wrote:
| Yes, building anything non-trivial in CL will show the
| discerning programmer that there is nothing new under the sun.
| waynesonfire wrote:
| Could you clarify what you mean by 'there is nothing new
| under the sun' when referring to programming with Common
| Lisp? Are you indicating that Lisp has already introduced
| many of the concepts and features that are now found in
| modern programming languages, implying that contemporary
| languages have largely assimilated Lisp's ideas and
| paradigms?
|
| Your comment left me with a strange sentiment. I'm somewhat
| disheartening because it implies that learning Lisp might be
| redundant given that contemporary languages have already
| incorporated its best aspects.
| phoe-krk wrote:
| _> Are you indicating that Lisp has already introduced many
| of the concepts and features that are now found in modern
| programming languages, implying that contemporary languages
| have largely assimilated Lisp 's ideas and paradigms?_
|
| Yes. See effect handlers for an example, which are making
| rounds around the programming world as of late. They are
| equivalent to the Lisp condition system, except formalized
| to work in strongly statically typed programming
| environments.
|
| _> I 'm somewhat disheartening because it implies that
| learning Lisp might be redundant given that contemporary
| languages have already incorporated its best aspects._
|
| Sort of, lots of things have thankfully trickled from Lisps
| to other languages (including whole languages like Julia).
| The pleasant feeling of conversing with the language and
| programming bit by bit in it is hard to replicate with
| things like LSPs, though, since the implementation is
| always running in the background and programming in it is
| based on mutating it until it contains the program you
| seek.
| valcron1000 wrote:
| > They are equivalent to the Lisp condition system
|
| Not exactly correct due to the lack of higher order
| effects (https://news.ycombinator.com/item?id=20513370),
| but the condition system is "good enough" for a lot of
| use cases
| phoe-krk wrote:
| TIL. The way I understand it, that's because CL is not
| required to perform CPS on its code and no CL
| implementation exists that does it on its own.
| corinroyal wrote:
| > I'm somewhat disheartening because it implies that
| learning Lisp might be redundant given that contemporary
| languages have already incorporated its best aspects.
|
| Indeed, Lisp is no longer as revelatory as it once was,
| since many innovations have been adopted, even surpassed in
| specific cases. Still, no other language gives you the
| total package. The environment is far more than the sum of
| its features list. CL just gets out of your way and allows
| you to think about problems not programming.
| pjmlp wrote:
| Except the little detail that JIT/AOT toolchains still aren't
| as widespread as they should be, with several languages
| offering only one variant, and there as still quite a few
| Lisp tricks either left behind in modern IDEs, or with
| various kinds of support depending on the language, like
| accessing everything across language and runtime, hot code
| reloading, time travel debugging.
|
| Ah, and most relevant, many folks still believe that writing
| OSes in what was once a macro Assember for PDP-11 is the only
| way.
| tiberius_p wrote:
| Lisp is great for creating your own domain specific languages.
| S-expressions are basically abstract syntax trees written as
| code. Thus you can take any code written in any language and
| "lispify" it into an S-expression. Then you can apply various
| transformations/analyses on this expression to achieve various
| goals:linting, semantic modeling, compiling to machine
| code/bytecode, transpiling to another laguage, interpreting,
| optimizing, etc. Common Lisp also has the possibility of on-
| the-fly recompilation of classes and methods/functions which
| can be useful for debug and incremental development.I don't
| have much experience in the web development area but I would
| incline to think that you won't get much added value from using
| CL compared to other languages/frameworks. It can be useful if
| you want to develop your own framework with custom language
| constructs and features. But if you want to fast prototype a
| webapp idea you're better off trying the more popular
| solutions.
| corinroyal wrote:
| I'm learning programming at age fifty-four and have chosen
| Common Lisp as my one language for life. If you want something
| easy to learn with a ton of support pick Python, Elixir, and/or
| JS. CL sucks for mini-projects since the learning curve
| requires serious commitment and is SO different from what
| people are used to. CL requires a long-term commitment and
| demands the programmer challenge pop programming trends and
| deeply entrenched styles. You have to think beyond today to
| what could be and what once was. But if you're willing to do
| that, there is no better language. Not Haskell, not OCamel, not
| Rust/Go/Julia/Clojure/Scheme, or the current lang du jour.
| Whatever limitations Common Lisp had in the past are long gone.
|
| SBCL is blazingly fast, CL abstractions are profound yet
| practical. The type system gives you power without pettiness.
| Language-oriented programming is a superpower in a world of cut
| and paste library-oriented programming. Image-based computing
| often allows one to skip the impedance mismatch with DBs. In
| many cases and you can just persist the data structures as they
| are or serialize them where needed. The tooling with Roswell,
| Quicklisp, Qlot, Doom Emacs, and Sly make prototyping and
| exploratory programming wiz by. CLOG, Reblocks and Hunchentoot
| provide powerful abstractions for web programming, but Phoenix
| with Liveview is probably better for most. The debugging
| experience is so insanely powerful it freaks me out and makes
| other systems look rudimentary. CLOS, the object system, is
| best of breed and makes most of the standard criticisms of OO
| programming moot. The homoiconic list-based syntax and prefix
| notation are beautiful and never get in your way. Parentheses
| are invisible. The condition system makes flow control and
| error handling in other systems seem rigid and convoluted.
| Aspect-oriented programming is just what we do, not a thing
| tacked on. Macros and the meta-object protocol allow you to
| build a language on top of Lisp that allows users to
| conceptualize problems using nouns and verbs they already know.
|
| Drop into Coalton or Shen for strong, static typing where
| necessary, or April (hosted APL) for array wizardry that makes
| NumPy look like data-flow programming in Basic on a Timex
| Sinclair with a cassette drive. You can slice and dice whole
| datasets in a few characters of code. Bundle existing C libs
| with CFFI when you find a good one you need. Lisp-based systems
| are alive and grow and change as requirements do. It's harder
| to program yourself into a corner. Refactoring is continuous
| and mundane. In-source documentation is the right place for it,
| but Lispers tend to be shamefully lax in providing it. Shaaame!
| Newer Lispers tend to be better about docs--the culture is
| changing. Often you ask a question and get no response. Other
| times you get a detailed response from a legendary mind and
| just sit there in awe working your way through their thinking
| and feeling your inadequacy. The code is about as succinct as
| it can be to maintain readability. There are two camps on
| readability, some experienced Lispers find it harder, and most
| find it much easier to parse than ALGOL-derived syntax.
|
| Once mastered, quick things are quick, hard things are
| straightforward, and impossible things are doable. This is a
| system for people who need, not want, to change the world. It
| gives single programmers and small teams the power to take on
| armies of bureaucratic programmers. But you have to be willing
| to break the mold, handle charges of elitism, not be required
| to justify your choice to managers, tolerate a small hiring
| pool, train newbies hard and long, not get freaked out using
| some libs that are stable and haven't been updated in years,
| deal with the pace of development of a small community, have
| the patience and joy in problem-solving to handle frequent
| bafflement, read a ton of source code rather than search the
| forums, and be willing to roll your own when needed. If you can
| handle all the idiosyncrasies and have a burning need for
| elegance and power, then CL will reward and surprise into until
| dementia takes you.
|
| In short, all the good things you've heard are true, many of
| the standard critiques are uninformed, and problems people talk
| about that apply to most languages often don't apply.
| pjmlp wrote:
| Additionally jump into LispWorks or Allegro Common Lisp, to
| enjoy how the survivors from Common Lisp days with a full
| blown IDE feels like.
| tome wrote:
| You have an extremely deep understanding of the discipline of
| computer programming for someone who has only just started to
| learn!
| corinroyal wrote:
| How kind of you to say. I held off on learning programming
| for so long due to my visceral disgust with C/UNIX and
| ALGOL syntax. I just knew it was the wrong set of
| abstractions that have trapped us all in a grey hellscape
| of mediocrity and wasted potential. When I was a kid I
| turned turtles into a spirograph in Logo on an Apple II. It
| ruined me. I didn't know Logo was functional or Lisp-
| inspired.
|
| When I found functional programming in Erlang I got SO
| excited. When I found Common Lisp, decades of pent-up
| frustration melted away and I knew I'd come home. I guess
| my Unix Hating led to some intuitive thinking over the
| years and I've been making up for lost time over the past
| couple of years and mapping what I knew I wanted to what
| has been there in CL all along.
| massysett wrote:
| "not get freaked out using some libs that are stable and
| haven't been updated in years"
|
| In this vein, it's great that decades-old Common Lisp books
| are still current. The paucity of Web content is not as bad
| as it seems: you can get a real book.
| mark_l_watson wrote:
| +1 nice summary! I have been using Common Lisp since the
| early 1980s and I also love the language. For my own Lisp
| hacking pleasure, I add a few Schemes to the mix, but that is
| often a (fun) distraction for me, and I would be better off
| sticking with CL (or Python for deep learning projects).
|
| Do you have a blog where you share your learning experiences?
| corinroyal wrote:
| OMG! This is what I'm talking about with Common Lisp. One
| minute you're a washed-up slacker, the next Mark L. Watson
| speaks to you. I'm winding my way through "Loving Common
| Lisp, or the Savvy Programmer's Secret Weapon" as we speak
| and loving it. Thank you!
|
| I don't have a blog and haven't gotten far enough in my
| learning to make anything useful, but I do plan to produce
| a newbie's guide to help people get started quickly. My
| perspective as an older person for whom CL is my first
| language could be valuable since my sticking points are
| different and I don't yet have bad habits to break.
| wait_a_minute wrote:
| Hello my friend, I am very pleased to make your acquaintance
| and I am very excited about your journey. I am also very
| impressed that for someone who is newly learning the field,
| you already are so well-spoken and knowledgeable about the
| language and the tools. Thank you so much for your response.
| I also appreciate that you are only a little older than my
| parents, and if you are learning so well and so quickly then
| that fills me with much inspiration and excitement for the
| prospects of continued enjoyment of programming and software
| development for more decades to come. It's really exciting to
| know that anyone can learn at any age, and I wish you much
| enjoyment and success on your journey. If you were to create
| a developer blog, I'd read it!
|
| So far the language I've experienced the most power with is
| Python, and your description of Lisp's power and tooling are
| very intriguing. I will take note of your recommendations and
| play around with the tools you described. It is worth the
| investment if it means unlocking something even more powerful
| than Pythonic thinking and code.
|
| Do you find that one needs to be well-versed in Emacs to
| fully appreciate the CL stack you described and the
| capabilities of the language itself? Would you learn Emacs
| separately/after spending time building things with CL, or is
| building things with CL in Emacs part of the entire
| experience?
| f1shy wrote:
| Not so recent, about 6 years ago, I had to communicate with
| many instruments (PS, Oscilloscope, SMU, etc) to test a new
| ASIC we developed. There where hundreds of tests to be done. We
| wanted to automate the measurement and evaluation of results,
| because they were so many. Also there where 5 fabs and 2
| suppliers with different design, but "pin compatible". I did
| the whole framework in emacs lisp, I had to implement ONC RPC
| and LXI on top to speak to the instruments... The whole thing
| took me 2 weeks. At the time I had no idea of Elisp; only a
| little vit of scheme. I was proficient in C, and I would say it
| had taken me at least 6 Months to do the same
| worthless-trash wrote:
| I've written a few small CL web applications( with about 100
| users active a day), along with a few terminal applications
| (with only ~10 users). Other languages I know is C , Erlang,
| Elixir and a bit of python. This will end up sounding a bit
| evangelical but so be it.
|
| I feel that the lisp code was easier to write and reason about,
| the being able to hot reload code from the repl significantly
| decreased the time to completion. I also 'connect' to a
| networked repl when sentry reports an unhandled error to figure
| out what has gone wrong.
|
| You might be tempted to believe that CL repl is "similar
| enough" to python's repl, however this is NOT the case. Being
| able to redefine functions, variables and macros while working
| on the code (without a restart) allows you to deal with errors.
|
| The syntax is a 'no brainer', Extreme consistency in function
| calls means that you don't need to think about it. Other
| languages which SOMETIMES use infix, sometimes require
| brackets, that is just crazy.
|
| Lisp libraries have less churn than 'modern languages', some
| libraries have not been touched for some time, unlike
| python/ruby/js. The code does not seem to rot and old lisp code
| runs on modern implementations.
|
| I work in emacs, lem, I know people who use vscode and alive,
| and vim. There is no 'hard' requirement to use emacs, you will
| get by as long as you have 'emacs like' repl integration.
|
| All in all, I do not regret working in lisp. It doesn't have
| the cult of the other languages and I'm fine with that.
| msk-lywenn wrote:
| I'd rather say there is a definite cult over lisp. But it's
| very different from the other languages which I'd qualify as
| rather hardcore. Lisp's cult is a magical cult. No other
| language as such amazing stories as the space probe remotely
| debugged from earth with a repl, the extreme hot reload and
| mystical intertwining of assembly on PS2 of Jak & Daxter's
| GOAL, the MIT course with a Fantasia level of teaching, The
| symbolic machines, etc.
|
| The only other language like that I can think of is
| smalltalk.
| vindarel wrote:
| I use a couple web apps in production(c). The development
| experience is awesome, deployment is easy, the runtime is fast,
| the language and the ecosystem are stable. CL being CL, you get
| many errors, including type errors, at compile time (hitting
| C-c C-c, the feedback is instantaneous). You have less needs
| for stupid unit tests. My Sentry dashboard is empty :) Coming
| from Python I appreciate all that.
|
| We have a choice of libraries, but no big batteries-included
| web framework, so you must be ready to assemble pieces (or
| simply, to know web development). Ex: a login system? There are
| examples to look at, not a use-and-forget library.
|
| A CL webserver coupled with a client library like HTMX is
| great. I don't recommend Reblocks (weblocks) or CLOG yet for
| serious stuff.
|
| resources: the Cookbook, my lisp-journey #web content, my last
| youtube video (@vindarel channel).
| wait_a_minute wrote:
| Thank you very much for referencing your latest video, I'm
| watching it and glad to have such a timely example of what
| the development process can actually look like for CL web
| applications. Really cool stuff, will subscribe. :)
| pfdietz wrote:
| Block/return-from is a lexical transfer of control that can be
| non-local (you can transfer out of a lambda or defun to an
| enclosing scope). For the dynamic equivalent there's catch/throw.
| Both transfers activate unwind-protect if they unwind the stack
| through it.
| brabel wrote:
| One of the only languages where I saw this non-local returns is
| Kotlin.
|
| You can return from a function from within a lambda (and I
| believe this works on any number of levels), for example:
| fun go(list: List<String>): Boolean { list.forEach
| { if (it.isEmpty()) return@go true } return false
| }
| gpderetta wrote:
| Longjmp in standard C, swapcontext in POSIX C. I think GCC
| allows gotos to the containing function from a local function
| (but I never used GCC local functions).
|
| Smalltalk, and I believe ruby, allow non local return from
| blocks.
| gumby wrote:
| longjmp simply restores the machine registers (including PC
| and SP) and thus doesn't respect any sort of unwind-
| protect, a concept unknown in C.
|
| unwind-protect is a more general form of the c++ raii (in
| fact c++ got raii from Common Lisp).
| Findecanor wrote:
| `longjmp` does not restore the machine registers on all
| platforms. The C standard guarantees only the contents of
| variables marked `volatile`: anything above that is
| implementation-dependent.
|
| I think that MSVC++ longjmp actually does proper
| unwinding, calling destructors in C++ functions on the
| stack, but don't quote me on that. I think it is also
| dependent on the compiler flags.
| gpderetta wrote:
| Implementing exception handling (with cleanup on unwind)
| on top of setjmp was not uncommon. GCC still does on some
| targets. But I'm sure you know this more than I do.
|
| I think that RAII is different from unwind-protect and
| other scope based cleanup (finally, defer, with) as it is
| tied to object lifetimes. The fact that automatic objects
| lifetimes are tied to scope is a nice feature, but RAII
| goes beyond that.
| gumby wrote:
| Well lisps don't really have destructors in the sense C++
| does; objects go out of scope and become unreachable. So
| unwind-protect makes cleanup (closing a file, for
| example) explicit, which it has to be.
|
| I wouldn't say RAII is "tied to object lifetime" except
| in its name; at least I think of it as every {} pair
| _defining_ an unwind-protect with object creation
| /destruction being how it is effected by the programmer.
| Perhaps that is the same thing as you said, simply viewed
| from opposite sides.
|
| I do like the automatic nature of RAII, though
| implementing a whole class for it always feels clumsy to
| me even after doing it for decades.
| gpderetta wrote:
| What I mean is that if I add an instance of a class with
| a non trivial destructor from a container and later
| remove it, the destructor is automatically invoked. This
| is different from an unwind protect.
| lispm wrote:
| Lisp uses UNWIND-PROTECT to implement that.
|
| For example WITH-OPEN-FILE closes the file automatically
| when leaving its scope. (with-open-
| file (stream "hello.world") (read stream))
|
| WITH-OPEN-FILE is a macro and expands into OPEN and CLOSE
| operations, protected by an UNWIND-PROTECT.
|
| Thus anything where a destructor would automatically
| clean things up is done in Lisp behind the scenes
| automatically using an UNWIND-PROTECT form.
| gpderetta wrote:
| That's again an example of cleanup associated with scope.
| I understand what you can do it with unwind-protect and
| friends.
|
| But the essence of RAII is more than that.
|
| In c++ if I add an opened file object to some collection
| and later remove it or destroy the collection, it is
| implicitly cleaned up.
|
| For example let's say you are implementing an n-way out
| of core merge: in c++ you would create a priority queue
| of files objects ordered by the front current from item.
| You pop the front file object read the item and, if the
| file is not empty, push it back into the queue. Cleanup
| is implicit by removing the file from the queue and not
| explicitly adding it back. On early exit (because of an
| error or exception) the queue is automatically destroyed
| and recursively all the file objects.
|
| There might be a way to implement this recursively with
| unwind-protect, but I think it is less natural.
|
| For example python has ExitStack, which in practice is an
| ad-hoc container that supports recursive cleanup of
| contained objects, but is still not as convenient as
| having all containers do proper cleanup.
| kazinator wrote:
| The object is not exactly removed from the container. It
| is removed from existence. The object in that situation
| resides in the container physically. It is constructed
| there and destroyed. It does not exist outside of the
| container afterwards, or at any other time.
|
| This is a low-level memory management strategy being
| conflated with object-orientation, that is alien to
| higher level languages.
| gpderetta wrote:
| Well yes, it works well in c++ because the language has a
| strong distinction between value semantics and reference
| semantics, so when you remove a value from a container it
| must clearly be destroyed. A GC'd language with aliased
| references can't call destructors in this case. At best
| can do it when the object is collected.
|
| Yet I think an high level language could have the same
| value/reference distinction. Or you could do it with
| linear types.
| oumua_don17 wrote:
| >> in fact c++ got raii from Common Lisp
|
| I know and understand this is true.
|
| Can you point to any sources (projects, papers) that
| further substantiate this?
| gumby wrote:
| No, but Tiemann might remember as I remember introducing
| him to unwind-protect (not that he invented RAII afaik,
| nor would claim to have)
| adrian_b wrote:
| The concept of RAII has emerged gradually and it would be
| hard to pinpoint a moment for its appearance. I am not
| aware of any specific feature of RAII that has appeared
| in Common Lisp before other languages.
|
| The concepts of constructors and destructors have been
| introduced by C.A.R. Hoare in November 1965, in "Record
| Handling", a proposal for the extension of Algol.
|
| At that time, Hoare was using the Cobol terms, i.e.
| "record" for what later was named "object" and "record
| class" for what later, in Simula 67, was abbreviated to
| "class". All the "records" discussed by Hoare were
| allocated dynamically, in the heap.
|
| Constructor (Hoare, 1965-11): "In order to bring records
| into existence in the first place, the record class
| identifier should be used as if it were a function
| designator"
|
| Destructor (Hoare, 1965-11): "a standard procedure
| "destroy" is proposed, which takes as parameter a
| reference to a record, and which reverses the effect of
| having created that record"
|
| The next step towards RAII has been done by Bjarne
| Stroustrup in "C with Classes" in April 1980, when he
| made the invocation of the destructors implicit at the
| exit from a block, by introducing the special member
| function "delete" for this purpose. Despite the name, the
| 1980 "delete" member functions corresponded to what
| later, in C++, were renamed as destructors.
|
| So in 1980, RAII was complete, but it was not yet
| promoted as a universal strategy for managing resources.
|
| In 1980, Common Lisp did not exist.
|
| Most older Lisps did not have any concept similar with
| the Algol block, so it would have been impossible for
| them to invoke implicitly some cleanup functions at block
| exits. They relied only on the garbage collector, where
| there is no RAII in the Stroustrup sense, even if GC and
| RAII are alternative methods for avoiding the explicit
| invocations of "free", "close" and the like.
| lispm wrote:
| MDL had UNWIND in 1977 and Maclisp added UNWIND-PROTECT
| in 1978. I'll guess that Lisp Machine Lisp then got it,
| too. Common Lisp emerged 1981 onwards, largely based on
| the latter.
|
| In the Lisp Machine OS there is a concept called RESOURCE
| for manual memory management. For example the CHAOS
| network stack has to deal with network packets. There is
| a macro USING-RESOURCE, which allocates/gets an object
| and on exit frees it. The macro expands into a form using
| also UNWIND-PROTECT to ensure freeing a resource on non-
| local exit. I would think that this is from around 1980,
| for the MIT CADR machine.
| adrian_b wrote:
| Thanks for pointing to MDL:
|
| http://www.ifarchive.org/if-
| archive/infocom/info/MDL_Primer_...
|
| Nevertheless, the MDL UNWIND and the later UNWIND-PROTECT
| are more limited in applications and they require much
| more work from the programmer than the mechanism
| introduced by Stroustrup in 1980.
|
| With implicitly-invoked destructors, the destructor body
| is written once for each type of data, and normally there
| is no need to ever invoke it explicitly.
|
| After writing correctly the constructors and destructors,
| the programmer's work becomes identical with using a
| garbage collector, because the objects are allocated
| explicitly, but they are never deallocated explicitly.
|
| On the other hand, UNWIND is intended for handling
| exceptions. It can also be used as a normal cleanup
| strategy, but it still must be written every time for
| handling the exit from a block or from a hierarchy of
| nested blocks. In the latter variant, there is some
| economy in code writing, but the lazy deallocation is
| less efficient.
|
| The UNWIND of MDL has little resemblance to RAII, but it
| resembles the UNWIND of Mesa (programming language used
| at Xerox, starting with 1976, which has introduced many
| innovations that have been included only much later in
| most programming languages).
|
| It would be difficult to determine whether UNWIND has
| appeared first in MDL or in Mesa, or if both have taken
| it from another language, because experiments with
| exception handling were fashionable during those years
| and there were many places where various variants were
| tried.
| lispm wrote:
| UNWIND-PROTECT is a building block.
|
| Resource management in the MIT Lisp OS ca. 1980,
| approximate example.
|
| One would define a resource of arrays, where arrays can
| be allocated and deallocated. They will be managed via a
| pool. (defresource 2d-array (rows
| columns) :constructor (make-array (list rows
| columns)))
|
| Now user code would use the USING-RESOURCE macro, where
| it spans a dynamic scope. Entering the scope allocates
| the resource. Inside the scope the resource is allocated.
| Leaving the scope will automatically deallocate the
| resource and put it back into the pool. A deinitializer
| may free memory as needed. (using-
| resource (my-array 2d-array 100 100) ; get me a 100x100
| array from a pool (setf (aref my-array 42 42)
| 'the-answer) ; setting the array (print (aref
| my-array 42 42))) ; reading the array
|
| To make sure that the resource gets deallocated, the
| above macro form will expand to something using UNWIND-
| PROTECT: ... (unwind-protect
| (progn
| ; protected form (setf my-array (allocate-
| resource '2d-array 100 100)) ; allocate the array
| (setf (aref my-array 42 42) 'the-answer) ;
| setting the array (print (aref my-array 42
| 42))) ; reading the array
| (when my-array
| ; exit form (deallocate-resource '2d-array
| my-array))) ; deallocate the array
| ...
|
| This is an example of manual memory management using a
| pool of resources, where the DEALLOCATE is done always
| via UNWIND-PROTECT.
|
| Thus the user will not explicitly use UNWIND-PROTECT, but
| some macros which use it in their expansion...
| adrian_b wrote:
| Thanks for the explanation.
|
| I agree that this is pretty much equivalent to RAII.
|
| Nevertheless, it is also obvious that this was not a
| source of inspiration for Bjarne Stroustrup.
|
| He has started directly from the constructors and
| destructors of C.A.R. Hoare (1965-11) and Simula 67
| (1968-05, Kristen Nygaard & Ole-Johan Dahl).
|
| The only change is that in 1980 he has enhanced his
| compiler for "C with Classes" to generate automatically
| all the invocations to the appropriate destructors in all
| the block and function epilogues, relieving the
| programmer from this task.
| EdwardCoffin wrote:
| Smalltalk only allows the return from the block's lexically
| enclosing method, not an arbitrarily specifiable context
| like Common Lisp does. It's discussed a bit on c2.com [1]
|
| [1] https://wiki.c2.com/?SmalltalkBlockReturn
| xkriva11 wrote:
| In Pharo or Squeak, you can just send the "return:"
| message to any context (except contexts that have nowhere
| to return).
| formerly_proven wrote:
| Is Common Lisp the first kitchen sink language (ala C++)? It
| always seems to me like there's a lot of "Oh yeah, Common Lisp
| has a feature for this, too"-type blog posts, though very little
| about actual usage of it.
| pjmlp wrote:
| Common Lisp is the uniformization of what Lisp Machines across
| Genera, TI, and Xerox PARC (although Interlisp-D was a
| different species) were offering for a full graphics
| workstation, alongside other systems.
|
| It was as kitchen sink as having POSIX (basically a full blown
| UNIX specification), to be expected to fill in the stuff
| missing from ISO C standard library.
| int_19h wrote:
| It's a rather subjective assessment. ALGOL 68 and PL/I were
| apparently considered rather "kitchen sink" by the standards of
| their time.
___________________________________________________________________
(page generated 2024-01-21 23:02 UTC)