Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
SECD machine
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{Short description|Abstract machine as a target for compilers}} {{Infobox software | title = SECD machine | logo = <!-- File name without 'File:' --> | logo caption = | logo alt = | logo upright = | logo size = | screenshot = <!-- File name without 'File:' --> | screenshot alt = | caption = | other_names = | author = [[Peter Landin]] | developer = | released = {{Start date and age|1964}} | discontinued = Yes | latest release version = | latest release date = <!-- {{Start date and age|196y|mm|dd|df=yes}} --> | programming language = | operating system = [[Linux]], [[Microsoft Windows|Windows]], [[DOS]] | platform = [[Free Pascal]] on [[IA-32]], [[x86-64]] | included with = [[Lispkit Lisp]], [[Lisp (programming language)|Lisp]]/[[IBM System/370|370]], pure_LISP | size = ~ 76K, 185K, 920K | language = English | genre = [[Virtual machine|virtual]] and [[abstract machine]] | license = <!-- or |licence= --> | website = {{URL|skelet.ludost.net/sec}} | AsOf = }} The '''SECD machine''' is a highly influential (see: ''[[#Landin's contribution|Landin's contribution]]'') [[virtual machine]] and [[abstract machine]] intended as a target for [[compiler]]s of [[Functional programming|functional]] [[programming language]]s. The letters stand for <code>stack</code>, <code>environment</code>, <code>control</code>, <code>dump</code>, respectively, which are the [[Processor register|internal registers]] of the machine. The registers <code>stack</code>, <code>control</code>, and <code>dump</code> point to (some realizations of) [[Stack (abstract data type)|stacks]], and <code>environment</code> points to (some realization of) an [[associative array]]. The machine was the first to be specifically designed to evaluate [[lambda calculus]] expressions. It was originally described by [[Peter Landin]] in "The Mechanical Evaluation of Expressions" in 1964.<ref>{{Cite journal |last1=Landin |first1=P. J. |author1-link=Peter Landin |date=January 1964 |title=The Mechanical Evaluation of Expressions |doi=10.1093/comjnl/6.4.308 |journal=[[The Computer Journal]] |volume=6 |issue=4 |pages=308–320 |doi-access=free}}</ref> The description published by Landin was fairly abstract, and left many implementation choices open (like an [[operational semantics]]). [[Lispkit Lisp]] was an influential compiler based on the SECD machine,<ref>{{cite book |last1=Henderson |first1=Peter |date=1980 |title=Functional programming: application and implementation |publisher=Prentice-Hall International |location=Englewood Cliffs, New Jersey |isbn=0-13-331579-7}}</ref> and the SECD machine has been used as the target for other systems such as [[Lisp (programming language)|Lisp]]/[[IBM System/370|370]].<ref>{{cite conference |last1=Padget |first1=Julian |date=1988 |title=Three uncommon Lisps |publisher=School of Mathematical Sciences, University of Bath |conference=First International Workshop on Lisp Evolution and Standardization |publication-place=Bath, Avon, United Kingdom |url=https://www.softwarepreservation.org/projects/LISP/conference/iwoleas88/Padget-ThreeUncommonLisps.pdf |citeseerx=<!-- dead? 10.1.1.99.1028 --> |via=[[Computer History Museum]]}}</ref> In 1989, researchers at the [[University of Calgary]] worked on a hardware implementation of the machine, with the same rationale as a [[high-level language computer architecture]] related to a [[Lisp machine]].<ref>{{cite report |last1=Graham |first1=Brian |date=1 September 1989 |url=http://hdl.handle.net/1880/46590 |title=SECD: Design Issues |place=Calgary, Alberta, Canada |access-date=12 December 2024}}</ref> ==Landin's contribution== [[David Turner (computer scientist)|D. A. Turner]] (2012)<ref name=tfp12>{{cite web |url=https://www.cs.kent.ac.uk/people/staff/dat/tfp12/tfp12.pdf |title=D. A. Turner "Some History of Functional Programming Languages" in an invited lecture '''TFP12''', St Andrews University, 12 June 2012. See the section on Algol 60}}</ref> points out that the [[ALGOL 60]] programming language could not return functions from other functions (rendering functions no longer first-class). A function nested inside another function could refer to a variable living on the outer function's stack. If the nested function were returned from the outer function, then it would be referring to a variable in a stack frame that is no longer present. Turner notes that Landin's SECD machine solves this problem (thus allowing functions to return functions), as a function value is now represented with a [[closure (computer programming)|closure]] on the heap that can store the environment of variables it should use irrespective of what happens on the stack.<ref name=tfp12 /> ==Informal description== When evaluation of an expression begins, the expression is loaded as the only element of control '''<code>C</code>'''. The environment '''<code>E</code>''', stack '''<code>S</code>''' and dump '''<code>D</code>''' begin empty. During evaluation of '''<code>C</code>''' it is converted to [[reverse Polish notation]] (RPN) with <code>ap</code> (for [[apply]]) being the only operator. For example, the expression <code>F (G X)</code> (a single list element) is changed to the list <code>X:G:ap:F:ap</code>. Evaluation of '''<code>C</code>''' proceeds similarly to other RPN expressions. If the first item in '''<code>C</code>''' is a value, it is pushed onto the stack '''<code>S</code>'''. More exactly, if the item is an identifier, the value pushed onto the stack will be the binding for that identifier in the current environment '''<code>E</code>'''. If the item is an abstraction, a [[closure (computer science)|closure]] is constructed to preserve the bindings of its free variables (which are in '''<code>E</code>'''), and it is this closure which is pushed onto the stack. If the item is '''<code>ap</code>''', two values are popped off the stack and the application done (first applied to second). If the result of the application is a value, it is pushed onto the stack. If the application is of an abstraction to a value, however, it will result in a lambda calculus expression that may itself be an application (rather than a value), and so cannot be pushed onto the stack. In this case, the current contents of '''<code>S</code>''', '''<code>E</code>''', and '''<code>C</code>''' are pushed onto the dump '''<code>D</code>''' (which is a stack of these triples), '''<code>S</code>''' is reinitialized to empty, and '''<code>C</code>''' is reinitialized to the application result with '''<code>E</code>''' containing the environment for the free variables of this expression, augmented with the binding that resulted from the application. Evaluation then proceeds as above. Completed evaluation is indicated by '''<code>C</code>''' being empty, in which case the result will be on the stack '''<code>S</code>'''. The last saved evaluation state on '''<code>D</code>''' is then popped, and the result of the completed evaluation is pushed onto the stack contents restored from '''<code>D</code>'''. Evaluation of the restored state then continues as above. If '''<code>C</code>''' and '''<code>D</code>''' are both empty, overall evaluation has completed with the result on the stack '''<code>S</code>'''. ==Registers and memory== The SECD machine is [[Stack (abstract data type)|stack-based]]. Functions take their arguments from the stack. The arguments to built-in instructions are encoded immediately after them in the instruction stream. Like all internal data-structures, the stack is a list, with the '''<code>S</code>''' register pointing at the list's ''head'' or beginning. Due to the list structure, the stack need not be a continuous block of memory, so stack space is available as long as there is a single free memory cell. Even when all cells have been used, [[garbage collection (computer science)|garbage collection]] may yield additional free memory. Obviously, specific implementations of the SECD structure can implement the stack as a canonical stack structure, thus improving the overall efficiency of the virtual machine, provided that a strict bound be put on the dimension of the stack. The '''<code>C</code>''' register points at the head of the code or instruction list that will be evaluated. Once the instruction there has been executed, the '''<code>C</code>''' is pointed at the next instruction in the list—it is similar to an ''instruction pointer'' (or [[program counter]]) in conventional machines, except that subsequent instructions are always specified during execution and are not by default contained in subsequent memory locations, as is the case with the conventional machines. The current variable environment is managed by the '''<code>E</code>''' register, which points at a list of lists. Each individual list represents one environment level: the parameters of the current function are in the head of the list, variables that are free in the current function, but bound by a surrounding function, are in other elements of '''<code>E</code>'''. The dump, at whose head the '''<code>D</code>''' register points, is used as temporary storage for values of the other registers, for example during function calls. It can be likened to the return stack of other machines. The memory organization of the SECD machine is similar to the model used by most functional language [[interpreter (computer software)|interpreters]]: a number of memory cells, each of which can hold either an ''atom'' (a simple value, for example ''13''), or represent an empty or non-empty list. In the latter case, the cell holds two pointers to other cells, one representing the first element, the other representing the list except for the first element. The two pointers are traditionally named [[CAR and CDR|''car'' and ''cdr'']] respectively—but the more modern terms ''head'' and ''tail'' are often used instead. The different types of values that a cell can hold are distinguished by a ''[[Tagged architecture|tag]]''. Often different types of atoms (integers, strings, etc.) are distinguished as well. So, a list holding the numbers ''1'', ''2'', and ''3'', usually written as <code>(1 2 3)</code>, might be represented as follows: Address Tag Content (value for integers, car & cdr for lists) 9 [ integer | 2 ] 8 [ integer | 3 ] 7 [ list | 8 | 0 ] 6 [ list | 9 | 7 ] ... 2 [ list | 1 | 6 ] 1 [ integer | 1 ] 0 [ nil ] The memory cells 3 to 5 do not belong to our list, the cells of which can be distributed randomly over the memory. Cell 2 is the head of the list, it points to cell 1, which holds the first element's value, and the list containing only ''2'' and ''3'' (beginning at cell 6). Cell 6 points at a cell holding 2 and at cell 7, which represents the list containing only ''3''. It does so by pointing at cell 8 containing the value ''3'', and pointing at an empty list (''nil'') as cdr. In the SECD machine, cell 0 always implicitly represents the empty list, so no special tag value is needed to signal an empty list (everything needing that can simply point to cell 0). The principle that the cdr in a list cell must point at another list is just a convention. If both car and cdr point at atoms, that will yield a pair, usually written like <code>(1 . 2)</code> ==Instructions== * '''<code>nil</code>''' pushes a nil pointer onto the stack * '''<code>ldc</code>''' pushes a constant argument onto the stack * '''<code>ld</code>''' pushes the value of a variable onto the stack. The variable is indicated by the argument, a pair. The pair's car specifies the level, the cdr the position. So <code>(1 . 3)</code> gives the current function's (level 1) third parameter. * '''<code>sel</code>''' expects two list arguments, and pops a value from the stack. The first list is executed if the popped value was non-nil, the second list otherwise. Before one of these list pointers is made the new '''<code>C</code>''', a pointer to the instruction following '''<math>sel</math>''' is saved on the dump. * '''<code>join</code>''' pops a list reference from the dump and makes this the new value of '''<code>C</code>'''. This instruction occurs at the end of both alternatives of a '''<code>sel</code>'''. * '''<code>ldf</code>''' takes one list argument representing a function. It constructs a closure (a pair containing the function and the current environment) and pushes that onto the stack. * '''<code>ap</code>''' pops a closure and a list of parameter values from the stack. The closure is applied to the parameters by installing its environment as the current one, pushing the parameter list in front of that, clearing the stack, and setting '''<code>C</code>''' to the closure's function pointer. The previous values of '''<code>S</code>''', '''<code>E</code>''', and the next value of '''<code>C</code>''' are saved on the dump. * '''<code>ret</code>''' pops one return value from the stack, restores '''<code>S</code>''', '''<code>E</code>''', and '''<code>C</code>''' from the dump, and pushes the return value onto the now-current stack. * '''<code>dum</code>''' pushes a "dummy", an empty list, in front of the environment list. * '''<code>rap</code>''' works like '''<math>ap</math>''', only that it replaces an occurrence of a dummy environment with the current one, thus making recursive functions possible A number of additional instructions for basic functions like car, cdr, list construction, integer addition, I/O, etc. exist. They all take any necessary parameters from the stack. == See also == * [[CEK Machine]] * [[Krivine machine]] == References == {{Reflist}} == Further reading == * [[Olivier Danvy|Danvy, Olivier]]. [http://www.brics.dk/RS/03/33/ ''A Rational Deconstruction of Landin's SECD Machine'']. BRICS research report RS-04-30, 2004. ISSN 0909-0878 * Field, Anthony J. Field and Peter G. Harrison. 1988 ''Functional Programming''. Addison-Wesley. {{ISBN|0-201-19249-7}} * Graham, Brian T. 1992 "The SECD Microprocessor: A Verification Case Study". Springer. {{ISBN|0-7923-9245-0}} * Kogge, Peter M. ''The Architecture of Symbolic Computers''. {{ISBN|0-07-035596-7}} * {{Cite journal |last1=Landin |first1=P. J. |author1-link=Peter Landin |title=The next 700 programming languages |doi=10.1145/365230.365257 |journal=[[Communications of the ACM]] |volume=9 |issue=3 |pages=157–166 |date=March 1966 |s2cid=13409665 |url=http://fsl.cs.uiuc.edu/images/e/ef/P157-landin.pdf |access-date=2015-08-28 |archive-date=2010-06-20 |archive-url=https://web.archive.org/web/20100620004154/http://fsl.cs.uiuc.edu/images/e/ef/P157-landin.pdf |url-status=dead}} ==External links== *[https://skelet.ludost.net/sec/ SECD Mania], full collection {{DEFAULTSORT:Secd Machine}} [[Category:1964 in computing]] [[Category:Implementation of functional programming languages]] [[Category:Models of computation]] [[Category:Abstract machines]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:Cite book
(
edit
)
Template:Cite conference
(
edit
)
Template:Cite journal
(
edit
)
Template:Cite report
(
edit
)
Template:Cite web
(
edit
)
Template:ISBN
(
edit
)
Template:Infobox
(
edit
)
Template:Infobox software
(
edit
)
Template:Main other
(
edit
)
Template:Reflist
(
edit
)
Template:Short description
(
edit
)
Template:Template other
(
edit
)