PLAIis designed for upper-level courses that introduce the main ideas of programming languages. In the US, it is designed for students in their second- through fourth-years of college, as well as starting graduate students. However, PLAI has been used with students much younger, including in a few select high school classes.
The main issue with it is that some readers (like Apple Books) neither render a monospace typeface nor display background colors. Other readers do both just fine. So if you want the proper experience, use one that handles both.
One annoying problem is that the code is not formatted in a monospace typeface, which to my mind makes it a bit harder to read (and inline code may read like prose). However, most other aspects (including background coloring) have been preserved, and it looks quite usable.
Please join the group plai-notifications. It will be very low volume: postings only when there is something significant (on the order of at most a few a year). It is expressly not a discussion forum, to keep volume low.
The text is very comprehensive in the coverage of programming languages and in particular their implementation, although relatively little attention is paid to parsing -- the author is very clear about this choice, and I agree with it.read more
The text is very comprehensive in the coverage of programming languages and in particular their implementation, although relatively little attention is paid to parsing -- the author is very clear about this choice, and I agree with it.
The modularity is very good. Unlike other texts, the good *does not* follow a linear structure and encourages the student/reader/instructor to navigate it using their preferences. Despite this dynamic flow of control, the book remains surprisingly modular and consistent.
Unlike some other textbooks, this one does not follow a top-down narrative. Rather it has the flow of a conversation, with backtracking. We will often build up programs incrementally, just as a pair of programmers would. We will include mistakes, not because I don't know the answer, but because this is the best way for you to learn. Including mistakes makes it impossible for you to read passively: you must instead engage with the material, because you can never be sure of the veracity of what you're reading.
This is a traditional textbook exercise. It's something you need to do on your own. If you're using this book as part of a course, this may very well have been assigned as homework. In contrast, you will also find exercise-like questions that look like this:
The main programming language used in this book is Racket. Like with all operating systems, however, Racket actually supports a host of programming languages, so you must tell Racket which language you're programming in.
This textbook has been used in classes at: Brown University, Cal Poly, Columbus State University, Northeastern University, NYU, Reed College, UC-San Diego, UC-Santa Cruz, University of Rhode Island, University of Utah, Westmont College, Williams College, Worcester Polytechnic Institute.
This module shows students what trade-offs are involved in designing a programming language, and how those trade-offs ultimately influence programmer productivity. The module starts with a quick, example-based introduction to the basics of programming languages. It then continues with a series of problems involved in the design of several programming languages.
As an example, the students will be shown the design difference between imperative languages with state and functional programming languages with types and general recursion. These will form the basis to construct more involved programming languages and realistic, e.g. non-determinism, polymorphism, effects and exceptions.
Also, they will be taught how to translate the mathematical description of a programming language into its corresponding implementation.
Indicative examples are:
- Implementation of interpreters for C-like and Haskell-like languages.
- Problem solving. The problems will involve concepts such as parsing, evaluation, trees, graphs, memoization, randomization.
- Adding Language features: first order functions, polymorphism, effects, exceptions, types, algebraic data types.
The intended subject specific learning outcomes.
On successfully completing the module students will be able to:
1. Describe the behaviour of programs written in a small imperative and functional programming language using operational semantics
2. Translate these ideas from theory to practice by implementing an interpreter for the language
3. Adding basic features to a base language.
4. Writing algorithms using imperative (while loops) and functional (recursive operators) languages.
University of Kent makes every effort to ensure that module information is accurate for the relevant academic session and to provide educational services as described. However, courses, services and other matters may be subject to change. Please read our full disclaimer.
Most of my programming experiences has been with CPython (dynamic, interpreted), and Java (static, compiled). However, I understand that there are other kinds of interpreted and compiled languages. Aside from the fact that executable files can be distributed from programs written in compiled languages, are there any advantages/disadvantages to each type? Oftentimes, I hear people arguing that interpreted languages can be used interactively, but I believe that compiled languages can have interactive implementations as well, correct?
A compiled language is one where the program, once compiled, is expressed in the instructions of the target machine. For example, an addition "+" operation in your source code could be translated directly to the "ADD" instruction in machine code.
An interpreted language is one where the instructions are not directly executed by the target machine, but instead read and executed by some other program (which normally is written in the language of the native machine). For example, the same "+" operation would be recognised by the interpreter at run time, which would then call its own "add(a,b)" function with the appropriate arguments, which would then execute the machine code "ADD" instruction.
You can do anything that you can do in an interpreted language in a compiled language and vice-versa - they are both Turing complete. Both however have advantages and disadvantages for implementation and use.
Note that modern techniques such as bytecode compilation add some extra complexity - what happens here is that the compiler targets a "virtual machine" which is not the same as the underlying hardware. These virtual machine instructions can then be compiled again at a later stage to get native code (e.g. as done by the Java JVM JIT compiler).
A language itself is neither compiled nor interpreted, only a specific implementation of a language is. Java is a perfect example. There is a bytecode-based platform (the JVM), a native compiler (gcj) and an interpeter for a superset of Java (bsh). So what is Java now? Bytecode-compiled, native-compiled or interpreted?
Other languages, which are compiled as well as interpreted, are Scala, Haskell or Ocaml. Each of these languages has an interactive interpreter, as well as a compiler to byte-code or native machine code.
Once upon a time, long long ago, there lived in the land of computinginterpreters and compilers. All kinds of fuss ensued over the merits ofone over the other. The general opinion at that time was something along the lines of:
A one or two order of magnitude difference in the runtimeperformance existed between an interpreted program and a compiled program. Other distinguishing points, run-time mutability of the code for example, were also of some interest but the majordistinction revolved around the run-time performance issues.
Today the landscape has evolved to such an extent that the compiled/interpreted distinction is pretty much irrelevant. Manycompiled languages call upon run-time services that are notcompletely machine code based. Also, most interpreted languages are "compiled" into byte-codebefore execution. Byte-code interpreters can be very efficient and rival some compiler generatedcode from an execution speed point of view.
The classic difference is that compilers generated native machine code, interpreters read source code andgenerated machine code on the fly using some sort of run-time system. Today there are very few classic interpreters left - almost all of themcompile into byte-code (or some other semi-compiled state) which then runs on a virtual "machine".
A compiler will produce a binary executable in the target machine's native executable format. This binary file contains all required resources except for system libraries; it's ready to run with no further preparation and processing and it runs like lightning because the code is the native code for the CPU on the target machine.
An interpreter will present the user with a prompt in a loop where he can enter statements or code, and upon hitting RUN or the equivalent the interpreter will examine, scan, parse and interpretatively execute each line until the program runs to a stopping point or an error. Because each line is treated on its own and the interpreter doesn't "learn" anything from having seen the line before, the effort of converting human-readable language to machine instructions is incurred every time for every line, so it's dog slow. On the bright side, the user can inspect and otherwise interact with his program in all kinds of ways: Changing variables, changing code, running in trace or debug modes... whatever.
In the end, these days, interpreting vs. compiling is a trade-off, with time spent (once) compiling often being rewarded by better runtime performance, but an interpretative environment giving more opportunities for interaction. Compiling vs. interpreting is mostly a matter of how the work of "understanding" the program is divided up between different processes, and the line is a bit blurry these days as languages and products try to offer the best of both worlds.
3a8082e126