# A Small Interpreted Language

Size: px
Start display at page:

Transcription

1 A Small Interpreted Language What would you need to build a small computing language based on mathematical principles? The language should be simple, Turing equivalent (i.e.: it can compute anything that any other language can compute) and relatively easy to use. Assume the computing hardware is constrained to vonneumann processes, with memory, an ALU, and appropriate registers. We will also assume that we know about formal mathematical languages and the necessary mathematical pieces: representation, recognizer, constructor, accessor, invariants/facts, functions, and induction/recursion. Base Representation of Atoms First, the alphabet of a language is simply a collection of unique identifiers, called atoms. The essential memory management trick is to divide each memory cell into two parts, an address part (call it First) and a contents part (call it Rest). Addresses are also called pointers. We begin with an array of empty cells, each having some empty representation in both the First and the Rest parts. This is the free list of memory cells. The ground: We need an atom which means nothing, the null atom. Call it nil. The symbol table: This table consists of a collection of non-empty memory cells, one cell for each atom in the language. The First part of an atom cell contains nil. The actual literal representation of the atom is in the Rest of the cell. The symbol table is a dynamic array. Constructor of Compound Expressions We need to construct compound expressions. Consider an expression which uses two atoms, say FOO BAR. The symbol table contains each atom, so all we need is a way to connect them. This can be done simply by building another memory cell which contains the two addresses of FOO and BAR. We put all atom addresses in the First part of a cell (see cell 005 below) and connecting addresses in the Rest part. The instruction to build connecting cells is called Cons. The end of an expression has nil in the Rest. If we build the expression (TRUE BAR TRUE FOO) in cell 007, memory would look like this: Address F i r s t Rest 000 nil nil symbol table 001 nil FOO 002 nil BAR 003 nil BAZ 004 nil TRUE end of symbol table the expression (FOO BAZ) end of expression the expression (TRUE BAR TRUE FOO) end of expression 011 empty empty begin free list... 1

2 To construct an expression, we Cons smaller pieces together. For instance: Cons JOHN (TRUE BAR TRUE FOO) ==> (JOHN TRUE BAR TRUE FOO) The operational memory changes are: 011 nil JOHN the atom JOHN connect JOHN to (TRUE BAR TRUE FOO) 013 empty empty Consider Consing two compound expressions together: Cons (FOO BAZ) (TRUE BAR TRUE FOO) ==> (FOO BAZ TRUE BAR TRUE FOO) This operation is slightly more complex. For the entire expression to begin in cell 012, we need memory to end up as (BAZ TRUE BAR TRUE FOO) (FOO BAZ TRUE BAR TRUE FOO) 013 empty empty Several design decisions are involved with this result. Technically, we have used structure sharing for (TRUE BAR TRUE FOO) since both the original four atom expression and the final six atom expression use some of the same memory cells. However, the front of the expression, (FOO BAZ) is not engaged in structure sharing, and this may seem a little unsymmetrical. As it is, (TRUE BAR TRUE FOO) is confounded with Rest (Rest (FOO BAZ TRUE BAR TRUE FOO)). An alternative which would allow us to continue to refer to the original would be to duplicate the four atom expression entirely in constructing the six atom expression. Note also that the construction is slightly different, rather than adding a symbol cell, as in the case of JOHN, we have added a cons cell. To acknowledge these differences, we might consider Cons of two compound expressions to be a different operation. Call it Append. Now the first object in a Cons operation is restricted to be an atom. Append is used when the first object is compound. To keep the language simple, we would want to be able to build new operations out of the existing ones. For this, we use a recursive definition: Append <obj1> <obj2> =def= If Isa-atom <obj1> then ERROR else if Is-empty <obj1> then <obj2> else Cons (First <obj1>)(append (Rest <obj1>) <obj2>) This recursive definition first does a type-check on <obj1>. It then tests the base case, that <obj1> is nil. Appending nothing onto <obj2> results in <obj2>. Otherwise we proceed one piece at a time. The recursion bottoms-out when Rest <obj1> is nil. For this to be the case, <obj1> must have only one atom, as in (BAZ), which is Consed onto <obj2>. At that time, BAZ is the First of <obj1>. Just prior to this case, <obj2> is actually (BAZ TRUE BAR TRUE FOO), since we have Consed BAZ to (TRUE BAR TRUE FOO). <Obj1> is (FOO BAZ), and we are about to Cons First <obj1>, i.e. FOO, onto (BAZ TRUE BAR TRUE FOO). 2

3 This description has backed up from the end to the beginning. Tracing the events in memory: Append nil (TRUE BAR TRUE FOO) ==> (TRUE BAR TRUE FOO) Append nil 012 empty empty begin free list By definition, cell 011 is the same as 007, so operationally this step is not necessary to take. We leave 011 free, treating Appending nil as a no-op. Cons BAZ (TRUE BAR TRUE FOO) ==> (BAZ TRUE BAR TRUE FOO) Cons FOO (BAZ TRUE BAR TRUE FOO) ==> (FOO BAZ TRUE BAR TRUE FOO) empty empty What we have done here is to specify exactly the sequence of operations on memory that result in the action of Appending. And we have used the single construction tool of Cons. This example illustrates the close connection between a software program, the attendant changes in memory, and the hardware architecture which unites both. Recognizer of Atoms The recognizer of each atom is a function which looks in the symbol table for the memory cell which contains that atom. For instance, the predicate Isa-atom is true if its argument can be found in the Rest portion of the symbol table. At this point, we have three separate memory areas (or uses): free cells, atom cells, and cons cells. Isa-atom: Is-empty: Equal: I s a - e x p r e s s i o n : Atom cells are recognized by having nil in the First part. Empty expressions can be uniquely recognized because they have nil in the Rest part. Tests if two atoms are the same atom. Cons cells are recognized as those cells having two addresses. An expression ends with nil in the Rest part. The above are close to operational definitions. Here are some slightly more elaborated operational definitions. We will assume that each part of a memory cell (address, first, rest) has eight bits. Is-empty <obj>: Assign nil a special binary code, , and put it in address An object is empty, that is, it is equal to nil, if the Rest part is equal to the code of nil. To distinguish nil from an empty cell on the free list, we could put a special code in free list cells, perhaps A better approach is to use only seven bits of the address for address information, and use the eighth bit for marking if a cell is free. This is the basis for many garbage collection algorithms. Is-empty <obj> =def= Equal (Rest <obj>)

4 Isa-atom <obj>: Test the encoding of <obj> against all the encodings in the Rest part of memory which also have nil in the First part. Isa-atom <obj> =def= for some memory cell (Equal (First <obj>) nil) and (Equal (Rest <obj>) <obj>) Here is another design choice: is nil an atom or not? If it is not an atom, we will have to have special tests for atoms vs nil. For simplicity, let s say it is an atom: (Isa-atom nil) is True This design choice is our first fact, or invariant. More generally: Isa-atom (Is-empty <obj>) =def= True iff (Is-empty <obj>) is True Recognizer of Expressions We can use the instructions First and Rest to access and decompose all expressions. (First <obj>) looks at the first part of memory for the specific object, (Rest <obj>) looks at the rest part. To recognize compound expressions, we test to see if each part of that expression is in the memory table, and the linking structure of the expression matches the rules for constructing that expression. Operationally: Isa-expression <obj> =def= (Isa-expression (First <obj>)) and (Isa-expression (Rest <obj>)) Since we know that decomposing an expression will end in either atoms or nil, we will have to add those rules: Isa-expression (Isa-atom <obj>) =def= True iff (Isa-atom <obj>) is True (Isa-expression nil) is True. This is another application of recursive decomposition. The rules specify the base cases, while the definition specifies the general recursive case. The two together specify a program. The definition above is another example of pseudo-code, that is, machine specific instructions written in a mathematical style that is independent of the specifics of any programming language, yet specific enough to be implemented in any language. Of course, a high level programming language accepts something very close to pseudo-code specification as valid input. Another strong advantage of pseudo-code is that it can be proven to be correct using the Induction Principle. 4

5 The primary reasons that current programming languages appear to be very different than pseudo-code are 1. Many programming tasks lack a formal model (i.e. they are hacks). 2. Many programming languages lack mathematical structure (i.e. they are machine architecture specific.) Accessors of Atoms and Expressions First and Rest are the accessors. They let us take apart an expression. In this implementation, First and Rest have simple mappings onto the idealized physical structure of memory. All objects except nil are constructed by Cons. Since Cons uses two objects as arguments, this means that all First and Rest parts are also objects. Eventually all objects end in nil, so nil is also an object, although a very special kind. Cons is related to First and Rest by the following invariant, or rule: <obj> = Cons (First <obj>) (Rest <obj>) This says that all valid objects have been constructed by Cons to have a First part and a Rest part in memory. Alternatively, all objects in memory can be accessed through their First and Rest parts. The essential mathematical condition is that all valid objects are decomposable into unique subcomponents which bottom-out at the base cases. This is simply to say that all compound expressions are defined recursively. Although recursive composition and decomposition are necessary to define data structures and algorithms, the more important aspect of recursive definition is to provide access to proof through the Induction Principle. Procedural languages do not provide this capability; they are thus immature. Declarative, functional, and mathematical programming languages all provide the capability of abstract proof (minimally in pseudo-code). Note that recognizing, constructing, and accessing an expression involve almost the same steps. The difference is in the initial goal and the final result. GOAL PROCESS R E S U L T Constructor: build a pattern rearrange memory the pattern is in memory Recognizer: Accessor: test a pattern access memory true if the pattern is accessible get a pattern access memory return the pattern if found 5

6 SUMMARY of the ABSTRACT DATA STRUCTURE FUNCTIONS First <obj> Rest <obj> Is-empty <obj> Isa-atom <obj> returns the expression indicated by the First of the <obj> returns the expression indicated by the Rest of the <obj> returns True if the cell containing <obj> has nil in Rest. returns True if the <obj> is in the Rest part of a cell and nil is in the First part. Isa-expression <obj> returns True if the <obj> has either nil or any address in the First part. Equal <obj1> <obj2> Cons <obj1> <obj2> In the case of atoms, returns True if both objects are in the Rest of the same symbol cell. In the case of compound expressions, returns True if following the addresses in the First leads to the same set of Rest symbol cells. builds an expression by adding <obj1> to the front of <obj2> I n v a r i a n t s The equality invariant (also called the Uniqueness Axiom) assures that each object is unambiguous. That is, objects are the same object when they are equal; equal objects are constructed and deconstructed in exactly the same way. This is a physical kind of equality, structural equality, in that the structure of memory is the same for two objects. It is not necessary that the same memory cells are used for both objects (structure-sharing), just that the contents of memory for both objects are the same. Recursively, Equal <obj1> <obj2> =def= (Equal (First <obj1>) (First <obj2>)) and (Equal (Rest <obj1>) (Rest <obj2>)) We need to support this definition with base cases. For instance, (Equal nil nil) is True This is also an example of the Induction Principle at work in our implementation. To implement an equality test for expressions, the computation will test for identical structure over all memory cells of both objects. The Induction Principle is the only guarantee that this recursive process will end. The only end point is (Equal nil nil), all other cases are failures. Note that equality for atoms is also covered in the above definition. What happens, though, when we have two atoms which have the same encodings, but each is in a different memory cell? This is an inconvenience for an implementation, since testing each object would require looking through the entire symbol table. A better approach is to insist that each atom is unique and occurs only once in the symbol table. This is why Equality and Uniqueness are the same ideas. 6

7 The uniqueness of atoms is implemented by having each new atom register itself in the symbol table. In the background, when an unrecognized, new atom is entered, the implementation verifies that it is new, and then puts it in the symbol table. To do this is to intern the atom. If the atom already exists, then the address of the cell which contains that object is associated with the new input. A different kind of equality refers to equality under transformation. The actual expressions may be different, but transformation rules allow us to say that the meaning of the different expressions is the same. This is semantic equality, also called algebraic equality and mathematical equality. Only defined transformations are allowed; all transformations (with the exception of Cons) are required to keep meaning consistent. It takes a special symbolic architecture to implement mathematical equality, mainly because transformations refer to sets or classes of objects rather than to specific objects. In the above, we have designed a literal architecture, as yet it has no capacity for dealing with sets of objects. Now on to the functional part of the language. We will elect to use lambda calculus as the mathematical model. Functions and Recursions A function is an expression with the function name first and then the arguments. (The order of operators and arguments is somewhat arbitrary, just so long as it is consistent and unambiguous.) For example: The Arithmetic Logic Unit (ALU) can process logical and arithmetic operators when applied to atoms. Internally, both arithmetic and logic are encoded by binary sequences, so it is the responsibility of the operator, or of a type test, to make sure that expressions meant to represent numbers are channeled to the arithmetic units and expressions intended to represent logic are channeled to the logic units. One way to implement the difference between logic and arithmetic is to assign another single bit in the memory cell that records the type of object in that cell. Note that silicon gates process only logic. Thus arithmetic objects must be encoded into a logical form for processing. In computation, logic is fundamental, arithmetic is derivative. All logic functions can be defined in terms of a single function, so we need only one primitive logic function. Let's use If (Nand and Nor are alternatives). If <obj1> <obj2> <obj3> If will evaluate <obj1> and then either evaluate <obj2> (if <obj1> is True) or evaluate <obj3> (if <obj1> is False). Here we have another function which uses different types of objects (the first example was Cons). In particular, <obj1> must be a logical type, returning either True or False. Function composition permits complex sequences of operations. A function expression can be put in any place that an atom can be put, since all functions will reduce to single atoms. To separate composed functions, we can use parentheses to contain each function expression. We will choose to evaluate all inner arguments first, then use these results to evaluate outer 7

8 functions. Lambda calculus permits another order of evaluation, outermost first. This choice is a design decision, and is based on mathematical characteristics of each form of evaluation. For example, an innermost evaluation: (* (+ 3 4) (+ 1 2)) or ((3 + 4) * (1 + 2)) means that expressions with atoms as arguments are evaluated, or reduced, first. The memory for this object would look like this: Address F i r s t Rest 000 nil nil symbol table 001 nil nil nil nil nil nil * end of symbol table expression ((3 + 4) * (1 + 2)) end of expression 014 empty empty begin free list... There are several things to note about the above memory configuration. Operators and numbers are not distinguished in memory, they are distinguished by what happens when they are handed to the ALU. Each operator has two arguments, but we have no way to have two references in one memory cell. The solution is to order the expression so that operators are followed by their arguments. When an operator is fetched for evaluation, the machine code recognizes that that operator requires two more fetches. Should a fetch return another operator, then the first operator waits until the second operator converts its two arguments into one result. Fetches occur by following the addresses in sequence. This is efficient since the address register (the register which keeps track of what to fetch next) need only be decremented by one to find the next memory cell. It is possible to turn all functions into one argument functions (the technique is called currying). This is effectively what has happened by storing the expression in the operator first form (also known as reverse Polish notation). Finally, consider how close the syntax of many programming languages is to what actually happens at the register transfer level of the computer. We are still at the very early stages of development of computing languages, since the syntax reflects low level data shuffling rather than high level task requirements. Progress means moving our profession toward human capabilities, and moving away from low level machine details. 8

9 We need a way to define arbitrary functions and a way to bind the variables of functions to values for the ALU to process. For example Square <obj> =def= (* <obj> <obj>) so that Square 4 => (* 4 4) => 16 First consider variables, names which stand for any valid object. We have been using the names <obj1>, <obj2>, etc. as variables names. The angle brackets notate that the name in question is not the name of a single thing, but rather it is the name of a class, or set, of things, all of which are of a particular type. Variables (or parameters, when the names are arguments of a function) are atoms also, so they are simply added to the symbol table. To assign a value to a variable symbol, we can put a reference to the location of the value we wish to associate with the variable in the First part of the memory cell for the variable. Thus variables are distinguished from objects representing a specific value because their First part is not nil. It is an error to access a variable which has nil as the First part. Objects which do have nil in the First part are called ground objects. The function which assigns ground objects to variable objects is called Let. We can use this same mechanism to store the definitions of functions. The memory cell which contains the name of the function in the Rest part can contain the address of the definition of the function in its First part. Consider the memory configuration for the above definition of Square: Address F i r s t Rest 000 nil nil symbol table 010 nil OBJECT 011 nil * end of symbol table SQUARE function definition end of function definition When the call Square 4 is added to memory we get: 016 nil 4 symbol table function call (Square 4) To bind OBJECT to the value 4, we use the call Let object 4: 019 nil LET symbol table function call (Let object 4) Finally we need to get the processor to actually evaluate the function call. Let's call this Eval. We can actually make Eval the default. Whenever a new expression is added it can be automatically evaluated. This just shifts the issue to needing an instruction to stop evaluation. Let's call this evaluation stopper Quote. 9

10 What the above memory configuration contains is Quote (Square 4), which simply puts the data structure Square 4 into memory. If we write the function Square 4, then evaluation will happen automatically. This process consists of changing the value of object from nil to 4, and following the sequence until a single atom is returned. That is, the function Let says to the processor: go to the symbol which immediately follows Let and put the address of the second symbol which follows Let (i.e. 4) in its First part. This results in OBJECT Now the definition of Square will find the value of OBJECT and use it rather than using the symbolic variable OBJECT. And, of course, symbolic variables are the only items in the symbol table which can contain something other than nil. There is a slight problem here because the symbol OBJECT might be used in more than one function. This can be handled in one of two ways: 1) make sure all of the symbols are unique, or 2) divide the symbol table into subtables which associate and isolate each function with its own variables. Finally, we simply use recursion directly as repeated actions of the same sort, since nothing in the above structuring stops this from working. The Function Eval In the above description, evaluation is an implicit action of the ALU. By claiming evaluation is automatic, we are committed to wiring the ALU in a specific way. However the above mechanism for handling memory can be made flexible by defining Eval in the programming language itself. This process is called meta-circular evaluation, cause it uses a language itself to define how that language should behave. All we have to do is to define the evaluation function by telling the system what to do when an expression is typed in. The function Eval takes two arguments, the expression to be evaluated and the binding environment, that is, an address of the memory array which contains all of the primitive functions and atoms (and any other symbols which we may have added) in the language. The binding environment contains the definitions of all user defined functions, and the values of each of the variables (function arguments). Since the binding environment does not change in this example, (i.e. we have not designed the language to establish separate environments for each function call), we will treat the token Eval to mean Eval-in-environment The definition of Eval which follows uses only primitive functions introduced above. Some of the syntax has been changed to make it more readable. This Eval function recognizes seven operators: F i r s t Rest Cons I f T h e n E l s e E q u a l Quote Let In addition, Eval uses built-in tests to determine the types of objects, as operationalized above. I s - e m p t y I s a - a t o m I s a - e x p r e s s i o n 10

11 Eval exp =def= If Isa-atom exp ;process atom If ((Is-empty exp) or (Equal exp (Quote True))) ;return the SYMBOL exp ; or its VALUE Get-value-in-env exp ;process expression If Isa-atom (First exp) ;process Atom in First* Let token (First exp) ;naming the atom If Equal token (Quote Quote) ;return what follows Second exp ;other operators If Equal token (Quote If) ;process logic operator EvalLogic (Rest exp) ;other operators If Equal token (Quote First) ;First of Eval of Rest First (Eval (Second exp)) ;other operators If Equal token (Quote Rest) ;Rest of Eval of Rest Rest (Eval (Second exp)) ;other operators If Equal token (Quote Isa-atom) ;Isa-atom Eval of Rest Isa-atom (Eval (Second exp)) ;other operators If Equal token (Quote Cons) ;Cons Eval of Rest** Cons (Eval (Second exp)) (Eval (Third exp)) ;other operators If Equal token (Quote Equal) ;Equal Eval of args Equal (Eval (Second exp)) (Eval (Third exp)) ;replace the token with Eval (Cons ;its value (Get-value-in-env token) (Rest exp)) ;compound First If Isa-expression (First exp) ;process expression EvalExp exp ERROR 11

12 EvalLogic exp =def= If Equal (Eval (First exp)) (Quote True) Eval (Second exp) Eval (Third exp)) ;if First is TRUE ;Eval second argument ;Eval third argument EvalExp exp =def= If Is-empty exp nil Cons (Eval (First exp)) (Eval (Rest exp)) ;if at the end ;return ground ;Eval the parts ; and put them together Notes: * process Atom in First: Here we have defined a syntax for parsing. Every expression begins with an atom or is an atom. If an expression begins with an atom, that atom is taken by the processor to be an operator, and thus a processing instruction. The operator Quote is the no-op. ** Cons Eval of Rest: This is again a syntax constraint. Once we have removed the beginning operator of an expression, what follows is either an atom, or another expression which itself begins with an atom operator. The syntax of the language is thus: Expression ::= Atom (Atom Expression*) The Kleene star means that an operator atom can have any number of following arguments. Note that this BNF specification is one of a regular language. Finally, note that a meta-circular language can evaluate its own definition of Eval, since the above definition is self-consistent. The Punch Line The above programming language actually exists, it is one of the very few oldest programming languages still in active use. Its name is LISP. In 1955, John McCarthy followed a similar line of reasoning in developing LISP. Currently LISP stands uniquely among programming languages in that it is rigorous, efficient, largely machine independent, and permits simulation of all other programming language models (such as procedural, functional, object-oriented, logical, and mathematical). As well, when the function Eval is processing input, LISP is interpreted, responding dynamically to new inputs and definitions, and requiring no compilation or linking. It thus provides a powerful interactive programming environment which supports real-time debugging and symbolic proof of correctness. 12

### Functional Programming. Pure Functional Languages

Functional Programming Pure functional PLs S-expressions cons, car, cdr Defining functions read-eval-print loop of Lisp interpreter Examples of recursive functions Shallow, deep Equality testing 1 Pure

### Functional Programming. Pure Functional Languages

Functional Programming Pure functional PLs S-expressions cons, car, cdr Defining functions read-eval-print loop of Lisp interpreter Examples of recursive functions Shallow, deep Equality testing 1 Pure

### CS 314 Principles of Programming Languages

CS 314 Principles of Programming Languages Lecture 16: Functional Programming Zheng (Eddy Zhang Rutgers University April 2, 2018 Review: Computation Paradigms Functional: Composition of operations on data.

### Functional Programming. Pure Functional Programming

Functional Programming Pure Functional Programming Computation is largely performed by applying functions to values. The value of an expression depends only on the values of its sub-expressions (if any).

### An Evolution of Mathematical Tools

An Evolution of Mathematical Tools From Conceptualization to Formalization Here's what we do when we build a formal model (or do a computation): 0. Identify a collection of objects/events in the real world.

### 6.184 Lecture 4. Interpretation. Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson

6.184 Lecture 4 Interpretation Tweaked by Ben Vandiver Compiled by Mike Phillips Original material by Eric Grimson 1 Interpretation Parts of an interpreter Arithmetic calculator

### Documentation for LISP in BASIC

Documentation for LISP in BASIC The software and the documentation are both Copyright 2008 Arthur Nunes-Harwitt LISP in BASIC is a LISP interpreter for a Scheme-like dialect of LISP, which happens to have

### 11/6/17. Functional programming. FP Foundations, Scheme (2) LISP Data Types. LISP Data Types. LISP Data Types. Scheme. LISP: John McCarthy 1958 MIT

Functional programming FP Foundations, Scheme (2 In Text: Chapter 15 LISP: John McCarthy 1958 MIT List Processing => Symbolic Manipulation First functional programming language Every version after the

### Modern Programming Languages. Lecture LISP Programming Language An Introduction

Modern Programming Languages Lecture 18-21 LISP Programming Language An Introduction 72 Functional Programming Paradigm and LISP Functional programming is a style of programming that emphasizes the evaluation

### Scheme. Functional Programming. Lambda Calculus. CSC 4101: Programming Languages 1. Textbook, Sections , 13.7

Scheme Textbook, Sections 13.1 13.3, 13.7 1 Functional Programming Based on mathematical functions Take argument, return value Only function call, no assignment Functions are first-class values E.g., functions

### Introduction to Scheme

How do you describe them Introduction to Scheme Gul Agha CS 421 Fall 2006 A language is described by specifying its syntax and semantics Syntax: The rules for writing programs. We will use Context Free

### 15 Unification and Embedded Languages in Lisp

15 Unification and Embedded Languages in Lisp Chapter Objectives Chapter Contents Pattern matching in Lisp: Database examples Full unification as required for Predicate Calculus problem solving Needed

### Scheme: Data. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Monday, April 3, Glenn G.

Scheme: Data CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Monday, April 3, 2017 Glenn G. Chappell Department of Computer Science University of Alaska Fairbanks ggchappell@alaska.edu

### Functional Programming

Functional Programming CS331 Chapter 14 Functional Programming Original functional language is LISP LISt Processing The list is the fundamental data structure Developed by John McCarthy in the 60 s Used

### Programming Languages Third Edition

Programming Languages Third Edition Chapter 12 Formal Semantics Objectives Become familiar with a sample small language for the purpose of semantic specification Understand operational semantics Understand

### Scheme Tutorial. Introduction. The Structure of Scheme Programs. Syntax

Scheme Tutorial Introduction Scheme is an imperative language with a functional core. The functional core is based on the lambda calculus. In this chapter only the functional core and some simple I/O is

### SCHEME AND CALCULATOR 5b

SCHEME AND CALCULATOR 5b COMPUTER SCIENCE 6A July 25, 203 In the next part of the course, we will be working with the Scheme programming language. In addition to learning how to write Scheme programs,

### Functional Programming. Big Picture. Design of Programming Languages

Functional Programming Big Picture What we ve learned so far: Imperative Programming Languages Variables, binding, scoping, reference environment, etc What s next: Functional Programming Languages Semantics

### 6.037 Lecture 4. Interpretation. What is an interpreter? Why do we need an interpreter? Stages of an interpreter. Role of each part of the interpreter

6.037 Lecture 4 Interpretation Interpretation Parts of an interpreter Meta-circular Evaluator (Scheme-in-scheme!) A slight variation: dynamic scoping Original material by Eric Grimson Tweaked by Zev Benjamin,

### SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

SCHEME 8 COMPUTER SCIENCE 61A March 2, 2017 1 Introduction In the next part of the course, we will be working with the Scheme programming language. In addition to learning how to write Scheme programs,

### Chapter 3. Describing Syntax and Semantics

Chapter 3 Describing Syntax and Semantics Chapter 3 Topics Introduction The General Problem of Describing Syntax Formal Methods of Describing Syntax Attribute Grammars Describing the Meanings of Programs:

### Project 2: Scheme Interpreter

Project 2: Scheme Interpreter CSC 4101, Fall 2017 Due: 12 November 2017 For this project, you will implement a simple Scheme interpreter in C++ or Java. Your interpreter should be able to handle the same

### Symbolic Programming. Dr. Zoran Duric () Symbolic Programming 1/ 89 August 28, / 89

Symbolic Programming Symbols: +, -, 1, 2 etc. Symbolic expressions: (+ 1 2), (+ (* 3 4) 2) Symbolic programs are programs that manipulate symbolic expressions. Symbolic manipulation: you do it all the

### Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

CS 6A Scheme Summer 207 Discussion 0: July 25, 207 Introduction In the next part of the course, we will be working with the Scheme programming language. In addition to learning how to write Scheme programs,

### INF4820: Algorithms for Artificial Intelligence and Natural Language Processing. Common Lisp Fundamentals

INF4820: Algorithms for Artificial Intelligence and Natural Language Processing Common Lisp Fundamentals Stephan Oepen & Murhaf Fares Language Technology Group (LTG) August 30, 2017 Last Week: What is

### CS 360 Programming Languages Interpreters

CS 360 Programming Languages Interpreters Implementing PLs Most of the course is learning fundamental concepts for using and understanding PLs. Syntax vs. semantics vs. idioms. Powerful constructs like

### Recursive Functions of Symbolic Expressions and Their Computation by Machine Part I

Recursive Functions of Symbolic Expressions and Their Computation by Machine Part I by John McCarthy Ik-Soon Kim Winter School 2005 Feb 18, 2005 Overview Interesting paper with By John Mitchell Interesting

### Chapter 3. Describing Syntax and Semantics ISBN

Chapter 3 Describing Syntax and Semantics ISBN 0-321-49362-1 Chapter 3 Topics Introduction The General Problem of Describing Syntax Formal Methods of Describing Syntax Attribute Grammars Describing the

### Chapter 3. Describing Syntax and Semantics

Chapter 3 Describing Syntax and Semantics Chapter 3 Topics Introduction The General Problem of Describing Syntax Formal Methods of Describing Syntax Attribute Grammars Describing the Meanings of Programs:

### 6.001 Notes: Section 8.1

6.001 Notes: Section 8.1 Slide 8.1.1 In this lecture we are going to introduce a new data type, specifically to deal with symbols. This may sound a bit odd, but if you step back, you may realize that everything

### COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

COP4020 Programming Languages Functional Programming Prof. Robert van Engelen Overview What is functional programming? Historical origins of functional programming Functional programming today Concepts

### Semantics via Syntax. f (4) = if define f (x) =2 x + 55.

1 Semantics via Syntax The specification of a programming language starts with its syntax. As every programmer knows, the syntax of a language comes in the shape of a variant of a BNF (Backus-Naur Form)

### 6.001 Notes: Section 6.1

6.001 Notes: Section 6.1 Slide 6.1.1 When we first starting talking about Scheme expressions, you may recall we said that (almost) every Scheme expression had three components, a syntax (legal ways of

### CSCC24 Functional Programming Scheme Part 2

CSCC24 Functional Programming Scheme Part 2 Carolyn MacLeod 1 winter 2012 1 Based on slides from Anya Tafliovich, and with many thanks to Gerald Penn and Prabhakar Ragde. 1 The Spirit of Lisp-like Languages

### Functional Languages. CSE 307 Principles of Programming Languages Stony Brook University

Functional Languages CSE 307 Principles of Programming Languages Stony Brook University http://www.cs.stonybrook.edu/~cse307 1 Historical Origins 2 The imperative and functional models grew out of work

### CSE 12 Abstract Syntax Trees

CSE 12 Abstract Syntax Trees Compilers and Interpreters Parse Trees and Abstract Syntax Trees (AST's) Creating and Evaluating AST's The Table ADT and Symbol Tables 16 Using Algorithms and Data Structures

### Functional Programming Languages (FPL)

Functional Programming Languages (FPL) 1. Definitions... 2 2. Applications... 2 3. Examples... 3 4. FPL Characteristics:... 3 5. Lambda calculus (LC)... 4 6. Functions in FPLs... 7 7. Modern functional

### Functional Languages. Hwansoo Han

Functional Languages Hwansoo Han Historical Origins Imperative and functional models Alan Turing, Alonzo Church, Stephen Kleene, Emil Post, etc. ~1930s Different formalizations of the notion of an algorithm

### 6.001 Notes: Section 15.1

6.001 Notes: Section 15.1 Slide 15.1.1 Our goal over the next few lectures is to build an interpreter, which in a very basic sense is the ultimate in programming, since doing so will allow us to define

### Warm-up and Memoization

CSE341 Spring 05 Due Wednesday, May 11 Assignment 4 Part I Warm-up and Memoization Warm-up As a warm-up, write the following Scheme functions: 1. Write the function foldl of the form (foldl func initial

### SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

SCHEME 7 COMPUTER SCIENCE 61A October 29, 2015 1 Introduction In the next part of the course, we will be working with the Scheme programming language. In addition to learning how to write Scheme programs,

### Recursive Functions of Symbolic Expressions and Their Application, Part I

Recursive Functions of Symbolic Expressions and Their Application, Part I JOHN MCCARTHY Review: Amit Kirschenbaum Seminar in Programming Languages Recursive Functions of Symbolic Expressions and Their

### Principles of Programming Languages 2017W, Functional Programming

Principles of Programming Languages 2017W, Functional Programming Assignment 3: Lisp Machine (16 points) Lisp is a language based on the lambda calculus with strict execution semantics and dynamic typing.

### Principles of Programming Languages

Principles of Programming Languages www.cs.bgu.ac.il/~ppl172 Lesson 6 - Defining a Programming Language Bottom Up Collaboration and Management - Elements of Programming Dana Fisman 1 What we accomplished

### Building a system for symbolic differentiation

Computer Science 21b Structure and Interpretation of Computer Programs Building a system for symbolic differentiation Selectors, constructors and predicates: (constant? e) Is e a constant? (variable? e)

### CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

CSE 413 Languages & Implementation Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341) 1 Goals Representing programs as data Racket structs as a better way to represent

### CS61A Discussion Notes: Week 11: The Metacircular Evaluator By Greg Krimer, with slight modifications by Phoebus Chen (using notes from Todd Segal)

CS61A Discussion Notes: Week 11: The Metacircular Evaluator By Greg Krimer, with slight modifications by Phoebus Chen (using notes from Todd Segal) What is the Metacircular Evaluator? It is the best part

### The PCAT Programming Language Reference Manual

The PCAT Programming Language Reference Manual Andrew Tolmach and Jingke Li Dept. of Computer Science Portland State University September 27, 1995 (revised October 15, 2002) 1 Introduction The PCAT language

### Goals: Define the syntax of a simple imperative language Define a semantics using natural deduction 1

Natural Semantics Goals: Define the syntax of a simple imperative language Define a semantics using natural deduction 1 1 Natural deduction is an instance of first-order logic; that is, it is the formal

### LECTURE 16. Functional Programming

LECTURE 16 Functional Programming WHAT IS FUNCTIONAL PROGRAMMING? Functional programming defines the outputs of a program as a mathematical function of the inputs. Functional programming is a declarative

### Scheme: Expressions & Procedures

Scheme: Expressions & Procedures CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Friday, March 31, 2017 Glenn G. Chappell Department of Computer Science University

### Introduction to Functional Programming in Haskell 1 / 56

Introduction to Functional Programming in Haskell 1 / 56 Outline Why learn functional programming? The essence of functional programming What is a function? Equational reasoning First-order vs. higher-order

### Lambda Calculus see notes on Lambda Calculus

Lambda Calculus see notes on Lambda Calculus Shakil M. Khan adapted from Gunnar Gotshalks recap so far: Lisp data structures basic Lisp programming bound/free variables, scope of variables Lisp symbols,

### 1. true / false By a compiler we mean a program that translates to code that will run natively on some machine.

1. true / false By a compiler we mean a program that translates to code that will run natively on some machine. 2. true / false ML can be compiled. 3. true / false FORTRAN can reasonably be considered

### Defining Program Syntax. Chapter Two Modern Programming Languages, 2nd ed. 1

Defining Program Syntax Chapter Two Modern Programming Languages, 2nd ed. 1 Syntax And Semantics Programming language syntax: how programs look, their form and structure Syntax is defined using a kind

### CSSE 304 Assignment #13 (interpreter milestone #1) Updated for Fall, 2018

CSSE 304 Assignment #13 (interpreter milestone #1) Updated for Fall, 2018 Deliverables: Your code (submit to PLC server). A13 participation survey (on Moodle, by the day after the A13 due date). This is

### Denotational Semantics. Domain Theory

Denotational Semantics and Domain Theory 1 / 51 Outline Denotational Semantics Basic Domain Theory Introduction and history Primitive and lifted domains Sum and product domains Function domains Meaning

### Functional programming with Common Lisp

Functional programming with Common Lisp Dr. C. Constantinides Department of Computer Science and Software Engineering Concordia University Montreal, Canada August 11, 2016 1 / 81 Expressions and functions

### Formal Systems and their Applications

Formal Systems and their Applications Dave Clarke (Dave.Clarke@cs.kuleuven.be) Acknowledgment: these slides are based in part on slides from Benjamin Pierce and Frank Piessens 1 Course Overview Introduction

### Procedural abstraction SICP Data abstractions. The universe of procedures forsqrt. Procedural abstraction example: sqrt

Data abstractions Abstractions and their variations Basic data abstractions Why data abstractions are useful Procedural abstraction Process of procedural abstraction Define formal parameters, capture process

### SCHEME The Scheme Interpreter. 2 Primitives COMPUTER SCIENCE 61A. October 29th, 2012

SCHEME COMPUTER SCIENCE 6A October 29th, 202 In the next part of the course, we will be working with the Scheme programming language. In addition to learning how to write Scheme programs, we will eventually

### CS 6110 S14 Lecture 1 Introduction 24 January 2014

CS 6110 S14 Lecture 1 Introduction 24 January 2014 1 Introduction What is a program? Is it just something that tells the computer what to do? Yes, but there is much more to it than that. The basic expressions

### 4.2 Variations on a Scheme -- Lazy Evaluation

[Go to first, previous, next page; contents; index] 4.2 Variations on a Scheme -- Lazy Evaluation Now that we have an evaluator expressed as a Lisp program, we can experiment with alternative choices in

### Below are example solutions for each of the questions. These are not the only possible answers, but they are the most common ones.

6.001, Fall Semester, 2002 Quiz II Sample solutions 1 MASSACHVSETTS INSTITVTE OF TECHNOLOGY Department of Electrical Engineering and Computer Science 6.001 Structure and Interpretation of Computer Programs

### The SPL Programming Language Reference Manual

The SPL Programming Language Reference Manual Leonidas Fegaras University of Texas at Arlington Arlington, TX 76019 fegaras@cse.uta.edu February 27, 2018 1 Introduction The SPL language is a Small Programming

### Spring 2018 Discussion 7: March 21, Introduction. 2 Primitives

CS 61A Scheme Spring 2018 Discussion 7: March 21, 2018 1 Introduction In the next part of the course, we will be working with the Scheme programming language. In addition to learning how to write Scheme

### Scheme in Scheme: The Metacircular Evaluator Eval and Apply

Scheme in Scheme: The Metacircular Evaluator Eval and Apply CS21b: Structure and Interpretation of Computer Programs Brandeis University Spring Term, 2015 The metacircular evaluator is A rendition of Scheme,

### 1.3. Conditional expressions To express case distinctions like

Introduction Much of the theory developed in the underlying course Logic II can be implemented in a proof assistant. In the present setting this is interesting, since we can then machine extract from a

### From the λ-calculus to Functional Programming Drew McDermott Posted

From the λ-calculus to Functional Programming Drew McDermott drew.mcdermott@yale.edu 2015-09-28 Posted 2015-10-24 The λ-calculus was intended from its inception as a model of computation. It was used by

### Functional programming in LISP

Programming Languages Week 4 Functional programming in LISP College of Information Science and Engineering Ritsumeikan University review of part 3 enumeration of dictionaries you receive a sequence of

### Logic and Computation

Logic and Computation From Conceptualization to Formalization Here's what we do when we build a formal model (or do a computation): 0. Identify a collection of objects/events in the real world. This is

### Fall 2017 Discussion 7: October 25, 2017 Solutions. 1 Introduction. 2 Primitives

CS 6A Scheme Fall 207 Discussion 7: October 25, 207 Solutions Introduction In the next part of the course, we will be working with the Scheme programming language. In addition to learning how to write

### CSCI.6962/4962 Software Verification Fundamental Proof Methods in Computer Science (Arkoudas and Musser) Section 17.1

CSCI.6962/4962 Software Verification Fundamental Proof Methods in Computer Science (Arkoudas and Musser) Section 17.1 Instructor: Carlos Varela Rensselaer Polytechnic Institute Spring 2018 CSCI.6962/4962

### Fall 2018 Discussion 8: October 24, 2018 Solutions. 1 Introduction. 2 Primitives

CS 6A Scheme Fall 208 Discussion 8: October 24, 208 Solutions Introduction In the next part of the course, we will be working with the Scheme programming language. In addition to learning how to write

### Building a system for symbolic differentiation

Computer Science 21b Structure and Interpretation of Computer Programs Building a system for symbolic differentiation Selectors, constructors and predicates: (constant? e) Is e a constant? (variable? e)

### Chapter 11 :: Functional Languages

Chapter 11 :: Functional Languages Programming Language Pragmatics Michael L. Scott Copyright 2016 Elsevier 1 Chapter11_Functional_Languages_4e - Tue November 21, 2017 Historical Origins The imperative

### Why do we need an interpreter? SICP Interpretation part 1. Role of each part of the interpreter. 1. Arithmetic calculator.

.00 SICP Interpretation part Parts of an interpreter Arithmetic calculator Names Conditionals and if Store procedures in the environment Environment as explicit parameter Defining new procedures Why do

### CS558 Programming Languages

CS558 Programming Languages Winter 2017 Lecture 7b Andrew Tolmach Portland State University 1994-2017 Values and Types We divide the universe of values according to types A type is a set of values and

### Basic Scheme February 8, Compound expressions Rules of evaluation Creating procedures by capturing common patterns

Basic Scheme February 8, 2007 Compound expressions Rules of evaluation Creating procedures by capturing common patterns Previous lecture Basics of Scheme Expressions and associated values (or syntax and

6. Syntax Learning objectives: syntax and semantics syntax diagrams and EBNF describe context-free grammars terminal and nonterminal symbols productions definition of EBNF by itself parse tree grammars

### Functional Programming Lecture 1: Introduction

Functional Programming Lecture 1: Introduction Viliam Lisý Artificial Intelligence Center Department of Computer Science FEE, Czech Technical University in Prague viliam.lisy@fel.cvut.cz Acknowledgements

### CS 415 Midterm Exam Spring 2002

CS 415 Midterm Exam Spring 2002 Name KEY Email Address Student ID # Pledge: This exam is closed note, closed book. Good Luck! Score Fortran Algol 60 Compilation Names, Bindings, Scope Functional Programming

### Pierce Ch. 3, 8, 11, 15. Type Systems

Pierce Ch. 3, 8, 11, 15 Type Systems Goals Define the simple language of expressions A small subset of Lisp, with minor modifications Define the type system of this language Mathematical definition using

### Lecture 5: The Halting Problem. Michael Beeson

Lecture 5: The Halting Problem Michael Beeson Historical situation in 1930 The diagonal method appears to offer a way to extend just about any definition of computable. It appeared in the 1920s that it

### Lambda Calculus. Gunnar Gotshalks LC-1

Lambda Calculus LC-1 l- Calculus History Developed by Alonzo Church during 1930 s-40 s One fundamental goal was to describe what can be computed. Full definition of l-calculus is equivalent in power to

### Introduction to LISP. York University Department of Computer Science and Engineering. York University- CSE V.

Introduction to LISP York University Department of Computer Science and Engineering York University- CSE 3401- V. Movahedi 11_LISP 1 Introduction to LISP Evaluation and arguments S- expressions Lists Numbers

### SOFTWARE ARCHITECTURE 6. LISP

1 SOFTWARE ARCHITECTURE 6. LISP Tatsuya Hagino hagino@sfc.keio.ac.jp slides URL https://vu5.sfc.keio.ac.jp/sa/ 2 Compiler vs Interpreter Compiler Translate programs into machine languages Compilers are

### FP Foundations, Scheme

FP Foundations, Scheme In Text: Chapter 15 1 Functional Programming -- Prelude We have been discussing imperative languages C/C++, Java, Fortran, Pascal etc. are imperative languages Imperative languages

### Scheme Basics > (butfirst '(help!)) ()

Scheme Basics > (butfirst '(help!)) () [The butfirst of a *sentence* containing one word is all but that word, i.e., the empty sentence. (BUTFIRST 'HELP!) without the inner parentheses would be butfirst

### Handout 9: Imperative Programs and State

06-02552 Princ. of Progr. Languages (and Extended ) The University of Birmingham Spring Semester 2016-17 School of Computer Science c Uday Reddy2016-17 Handout 9: Imperative Programs and State Imperative

### Intro. Scheme Basics. scm> 5 5. scm>

Intro Let s take some time to talk about LISP. It stands for LISt Processing a way of coding using only lists! It sounds pretty radical, and it is. There are lots of cool things to know about LISP; if

### Introduction 2 Lisp Part III

Introduction 2 Lisp Part III Andreas Wichert LEIC-T (Página da cadeira: Fenix) (I) Home Work (II) Data Types and Generic Programming (III) Lisp is Science (IV) Lisp Macros (V) More about Common Lisp an

### Introduction to Functional Programming and basic Lisp

Introduction to Functional Programming and basic Lisp Based on Slides by Yves Lespérance & Peter Roosen-Runge 1 Functional vs Declarative Programming declarative programming uses logical statements to

### Programming Languages

Programming Languages Tevfik Koşar Lecture - XIII March 2 nd, 2006 1 Roadmap Functional Languages Lambda Calculus Intro to Scheme Basics Functions Bindings Equality Testing Searching 2 1 Functional Languages

### B The SLLGEN Parsing System

B The SLLGEN Parsing System Programs are just strings of characters. In order to process a program, we need to group these characters into meaningful units. This grouping is usually divided into two stages:

### Introduction to Typed Racket. The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples

Introduction to Typed Racket The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples Getting started Find a machine with DrRacket installed (e.g. the

### Stating the obvious, people and computers do not speak the same language.

3.4 SYSTEM SOFTWARE 3.4.3 TRANSLATION SOFTWARE INTRODUCTION Stating the obvious, people and computers do not speak the same language. People have to write programs in order to instruct a computer what

### CSc 520 Principles of Programming Languages

CSc 520 Principles of Programming Languages 3: Scheme Introduction Christian Collberg collberg@cs.arizona.edu Department of Computer Science University of Arizona Copyright c 2005 Christian Collberg [1]