Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Where does this esoteric Pascal operator come from? (2017) (retrocomputing.stackexchange.com)
1 point by peter_d_sherman on Oct 17, 2024 | hide | past | favorite | 1 comment


Poster texdr.aft writes:

>"In 1972, operators named CATCH and THROW were added to Maclisp (I've reformatted the original announcement for convenience):

There is a new pair of break-away functions: CATCH, a FSUBR [i.e. a “special operator”, in Common Lisp terminology] which merely evals the first item in its arglist, and THROW, a SUBR [i.e., a normal function implemented in machine code] of one argument which breaks away back to the most recent CATCH, causing CATCH to return as its value the argument to THROW. If no THROWs take place, the CATCH merely returns the evaluation which it commenced. This mechanism is independent of ERRSET, and should alleviate problems for those who have been using ERRSET and ERR to do the job that CATCH and THROW now do. However, more stuff must be saved up when a CATCH or ERRSET is EVAL'd and thus code compiled by compilers prior to number 240 will not have compiled ERRSET evaluations correctly.

According to the implementer of the feature, Jon L White, it originated because

Sussman's later development of CONNIVER [successor of PLANNER, predecessor of SCHEME] showed the need for a sort of non-local GOTO, as a means of quickly aborting a computation (such as a pattern-matching data-base search) that had gone down a wrong path.

(This is precisely the sort of backtracking behavior mentioned in the accepted answer.)

The operators were generalized later that year:

CATCH and THROW are both FSUBRs

(

FSUBR definition/explanation: https://www.reddit.com/r/lisp/comments/fkxh5q/does_the_f_in_...

>"The actual difference between functions that were (F)EXPRs and those that were (F)SUBRs is clear. The former were interpreted (hence stored as an s-expression) and the latter compiled (stored as a pointer to a machine-code subroutine). But the meaning of the F isn't as intuitive.

It turns out that FEXPRs and FSUBRs were handed their arguments unevaluated, while the arguments to EXPRs and SUBRs were evaluated.

)

and have optional second args which are considered tags. (THROW FOO T1) will THROW back to the most recent setting of (CATCH (BAR) T1). (THROW FOO) will be caught by the most recent CATCH, regardless of any tag setting, and (CATCH (BAR)) will CATCH any THROW. However, (CATCH (BAR) T2) will never capture a (THROW FOO T1)—if there is no CATCH to match a given THROW (either one with the same tag name, or else a tag-less CATCH), then an UNSEEN-GO-TAG correctable error is done.

In contrast to branch, the “tag” in CATCH and THROW is not evaluated. A few years later, Lisp Machine Lisp changed the two operators so that

The tag argument comes first for both CATCH and THROW The tag is evaluated CATCH takes any number of forms to execute And these semantics were inherited into Common Lisp's catch and throw."

What an excellent history of what was quite possibly the first implementation of exception handling in a computer language!

Related:

Railway Oriented Programming:

https://fsharpforfunandprofit.com/posts/recipe-part2/




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: