Programming Language Concepts: A Comprehensive Overview
Programming Language Concepts
BNF and EBNF
Understand how to describe language features like loops using BNF or EBNF, and how to convert between them. For example:
- BNF Example: -> + | – |
-> * | / | - EBNF: -> } ->
Semantic Languages
Learn how attribute grammars, operational semantics, denotational semantics, and axiomatic semantics work and their applications.
- Attribute Grammars: Contain semantic information on parse tree nodes. Used for static semantics specification and compiler design.
- Operational Semantics: Used for language manuals, textbooks, and teaching programming. Two levels: Natural and Structural. Good for informal descriptions, complex for formal ones.
- Denotational Semantics: Recursive and the most abstract. Example: s = {, } VARMAP (ij,s) = vj
- Axomatic Semantics: Used for formal program verification and formal logic. Employs assertions to state relationships and constraints among variables. Example: a=b+1 {a>1} weakest precondition = b>0
Bindings
Understand the workings of static and dynamic binding rules. Binding time refers to when an association between an entity and its attribute (e.g., variable and value) occurs.
- Static Binding: Occurs before runtime and remains unchanged.
- Dynamic Binding: Occurs at runtime or changes during execution.
Scoping
Learn how static and dynamic scoping rules work.
- Static Scoping: Based on program text. Looks for declarations locally, then in larger enclosing scopes until one is found. Variables can be hidden by closer variables with the same name. Ada allows access to hidden values (e.g., unit.name).
- Dynamic Scoping: Based on the calling sequence. Subprogram calls determine which variable is linked.
Type Equivalence
Understand the difference between structural equivalence and name equivalence.
- Name Equivalence: Values have the same type based on the fully qualified name of their type (e.g.,
int a; int b;
– botha
andb
have the “int” type). - Structural Equivalence: Values have the same type if their types are structurally equivalent, regardless of the name. Name equivalence implies structural equivalence.
Data Types
Know various data structures (arrays, records, etc.), their advantages and disadvantages, supported data types in different languages, implementation details, type checking mechanisms, strongly typed languages, and the evolution of data types.
- Primitive Data Types: Not defined in terms of other data types, often reflecting hardware.
- Strings: Different implementations across languages (e.g., char array in C/C++, primitive in Python, object in Java).
- Arrays: Different notations and index types across languages (e.g., () in Fortran and Ada, [] in most others).
- Strong Typing: Type errors are always detected (e.g., Ada, Java, C#).
Expressions and Assignment Statements
Understand various expressions, operator precedence, operator overloading, type conversions and coercions, short-circuit evaluations, and assignment statements.
- Operator Overloading: Allows operators to have different meanings depending on their operands. Can improve readability but can also lead to confusion and errors.
- Type Conversions: Explicitly changing the type of a value.
- Coercions: Implicit type conversions. Can weaken type checking.
- Short-Circuit Evaluation: Evaluating only as much of an expression as necessary to determine its value.
Control Structures
Know selections, iterations, etc. in languages like Ada, Fortran, Python, and F#.
Ada Example
procedure Arr1 is
A: array(1..5) of Integer;
I: Integer;
begin
-- Read 'em in.
for I in 1..5 loop
Put("> ");
Get(A(I));
end loop;
-- Put 'em out in reverse order.
Put("[");
for I in reverse A'Range loop
Put(A(I));
if I > A'First then
Put(' ');
end if;
end loop;
Put_Line("]");
end Arr1;
Fortran Example
real :: v1(3), v2(3), m(3,3)
integer :: i,j
v1(1) = 0.25
v1(2) = 1.2
v1(3) = 0.2
! to the unit matrix
do i=1,3
do j=1,3
m(j,i) = 0.0
end do
m(i,i) = 2.0
enddo
Python Example
for loop_variable in object:
loop body
[else
else clause]
current, next, reset
list = [x ** 2 for x in range(12) if x%3 == 0]
# puts [0,9,36,81] in list
F# Example
let rec forLooop loopBody reps =
if reps <=0 then
()
else
loopBody()
forLoop loopBody, reps-1
// this is recursive, keeps calling loopbody for the number of reps.
Subprograms
Understand how in
, out
, and inout
parameters work, parameter passing mechanisms (value, reference, name, value/result), language implementations (activation records, static and dynamic links, scoping), displays, etc.
- Parameter Passing: Different languages use different methods (e.g., pass-by-value in C, pass-by-reference in C++).
- Activation Records: Data structures that store information about a subprogram’s execution.
- Static and Dynamic Links: Used to manage the scope of variables in nested subprograms.