Professional Documents
Culture Documents
SEN308 Lecture 1 1
SEN308 Lecture 1 1
.
Language Evaluation Criteria
Influences of Language Design
Language Categories by Paradigm
Language Design Trade-off
Compilation
A programming language is like a special way of talking to a computer. It lets you give the
computer instructions to do cool things like make games or draw pictures.
A programming language is a set of rules and words that let us write instructions a
computer can understand. Think of it like a code that tells the computer exactly what steps
to take
.
A programming language is a formal language with a defined syntax and semantics, used to
create precise instructions that a computer can execute. The syntax is the grammar, and
semantics define the meaning of those instructions
.
Better Understanding of the Significance of Implementation.
Go beyond your comfort zone: Learning concepts expands what you think is possible. Understanding
recursion, for instance, lets you solve problems in ways that simple looping doesn’t.
.
Programmers, in the process of developing software, are similarly constrained. The language in which
they develop software places limits on the kinds of control structures, data structures, and
abstractions they can use, thus, the forms of algorithms they can construct are likewise limited
Adapting as you grow: It's impossible to learn every language, but concepts let you quickly pick up
.
new ones as needed in your career.
It is preferable to use a feature whose design has been integrated into a language than to use a
simulation of that feature, which is often less elegant, more cumbersome, and less safe.
Shared foundations: Many languages share core concepts (variables, loops). Once you've grasped
these, new languages are just different ways of expressing them..
.
Focus on the differences: Understanding language theory allows you to focus on what's unique
about a language, speeding up the learning process.
For example, programmers who understand the concepts of object-oriented programming will
have a much easier time learning Ruby
Why things work the way they do: Studying concepts reveals how design decisions impact how
code runs. This helps you make informed choices about performance and how you structure your
programs.
Debugging gets easier: Understanding type systems, for example, helps you catch errors your
compiler may not, and it lets you reason about unexpected program behaviour
.
Understanding implementation issues is that it allows us to visualize how a computer executes
various language constructs
E.g. Stack (last in first out)
Write more elegant code: Grasping things like abstraction lets you write cleaner, more
maintainable code in any language you already use.
.
This course leads programmers to learn previously unknown and unused parts of the languages
they already use begin to use those features.
Push the boundaries: Perhaps someday, your insights into language design will contribute to new
.
languages that make programming even more powerful..
Scientific Applications:
• Appeared in the late 1940s and early 1950s.
• Large numbers of floating point computations.
• The most common data structures were arrays and matrices.
• The most common control structures were counting loops and selections
• FORTRAN, ALGOL 60 etc.
.
Business Applications:
• Appeared in the beginning of the 1950s.
• Business languages are characterized by facilities for producing elaborates, precise ways of
describing and storing decimal numbers and character data, and the ability to specify decimal
arithmetic operations.
• COBOL
Artificial Intelligence:
• Symbols rather than numbers manipulated, use of linked lists
• Now the new AI systems are written using MATLAB, Python, R, etc.
System Programming:
.
• Need efficiency because of continuous use
• C
Web Programming:
• Electronic collection of languages: Markup (e.g. HTML), scripting (e.g. Javascript or PHP), general
purpose e.g., Python
Mobile Applications
• Building applications for smaller devices
• React, Flutter, etc.
Operational Research - NUN 2024 Austin Olom Ogar
Language Evaluation Criteria
Readability: The ease with which programs can be read and understood
Writability: the ease with which a language can be used to create programs
Syntax: A clean and intuitive syntax helps developers quickly parse the structure of code.
Naming Conventions: Meaningful names for variables, functions, and classes make the code self-
documenting.
.
Formatting: Proper indentation, spacing, and line breaks visually organize code for better
comprehension.
Comments: Clear, concise comments explain the purpose of complex code sections or provide helpful
context.
Abstractions: Using functions, modules, and classes break down complex problems into manageable
units, improving readability.
Code Complexity: Keeping functions short and focused, and maintaining a reasonable level of code
nesting improves cognitive ease for the reader.
Operational Research - NUN 2024 Austin Olom Ogar
Readability contd..
Follow style guides: Adhere to established style guides for your chosen language (e.g., PEP 8 for
Python), ensuring consistency and familiarity.
Choose descriptive names: Avoid abbreviations or overly short names that lack clarity.
.
Use whitespace effectively: Indent appropriately and break code into logical blocks.
Add meaningful comments: Explain non-obvious sections of code, but don't state what the code itself
is already doing.
Refactor regularly: If code feels difficult to understand, break it down into smaller functions or rewrite
it.
Expressiveness: When a language is expressive, it provides constructs that align well with how humans
think about problems. It minimizes the need for convoluted workarounds.
Enjoyment: Programming with a language that feels natural and intuitive can increase job satisfaction
and reduce frustration.
Error Reduction: Writable languages often have features that help prevent common mistakes, such as
clear syntax or strong typing.
Abstractions: Functions, classes, and high-level data structures let you encapsulate complexity, making
it easier to reason about code at a higher level.
Syntax Clarity: Simple, well-defined syntax reduces ambiguity and mental overhead when writing code.
.
Conciseness: When a language lets you express a given idea with fewer lines of code, it generally
improves writability.
Orthogonality: A small set of well-integrated concepts that can be combined in flexible ways simplifies
and speeds up development.
Library Support: A rich standard library and ecosystem of packages often provide pre-built solutions for
common tasks, enhancing writability.
Focus on the problem domain: Design language constructs that map well to the sorts of problems the
language is meant to solve.
Study human cognition: Understand how people think about problems and design language features
.
that support those mental models.
Avoid excessive features: An overabundance of features can make a language cumbersome to learn
and use.
Provide sensible defaults: Smart defaults reduce verbosity and the number of decisions a developer
has to make while writing
Safety: In domains like healthcare, transportation, or finance, unreliable software can have severe,
even life-threatening consequences.
Cost of Errors: Bugs in unreliable software can lead to expensive downtime, lost data, and costs
associated with fixing the problems after release.
Reputation: Companies known for unreliable software suffer damage to their reputation and may lose
clients
Type Systems: Strong type systems help catch errors at compile time, preventing unexpected behavior
during execution. (Examples: Java, C#)
Memory Management: Languages that automate memory management (e.g., garbage collection)
.
prevent memory leaks and crashes caused by dangling pointers. (Examples: Java, Python)
Exception Handling: Robust error-handling mechanisms allow a program to recover gracefully rather
than crashing, enhancing reliability.
Bounds Checking: Ensuring that operations stay within the boundaries of arrays and other data
structures prevents unexpected behaviour and security vulnerabilities.
Testing Practices: Thorough testing, including unit testing, integration testing, and stress testing,
increases confidence in the program's reliability.
Choose appropriate languages: For critical systems, languages with strong type safety and memory
management features can greatly improve reliability.
Defensive Programming: Assume things might go wrong. Validate inputs and handle errors gracefully.
.
Unit Testing: Write unit tests that check the behaviour of individual code components.
End-to-End Testing: Test the entire system to simulate real-world usage scenarios.
Adopt good coding practices: Follow established coding standards to avoid common pitfalls and
improve code maintainability
Development Cost
Learning Curve: How quickly can developers become proficient in the language? Steeper learning
.
curves equate to longer training periods and delayed productivity.
Talent Availability: Are there enough developers skilled in the language? Scarcity of developers can
drive up salaries and recruitment costs.
Development Time: How expressive and fast to write in is the language? This directly impacts time to
market and labor costs.
Tooling: Are robust development tools, IDEs, and debugging tools available (and are they free or
require licensing)?
Costs contd..
Maintenance Cost
Readability: How easy is the code to understand? Code that's difficult to read incurs higher costs for bug fixing,
updates, and feature additions.
Community Support: An active community providing documentation, tutorials, and help with problems reduces
long-term maintenance costs.
Library Availability: Extensive libraries of well-maintained code mean less time spent reinventing the wheel and
.
lower maintenance overhead.
Execution Speed: Do programs written in this language run fast enough for the intended task? Slow execution
might mean needing more powerful hardware, increasing infrastructure costs.
Memory Profile: How much memory do programs written in the language consume? Memory-heavy languages
might necessitate hardware upgrades.
Platform Licensing: Do you need to pay licensing fees to run the language on certain operating systems or
servers?
Influences of Language Design
Technical Constraints
Computer Architecture: Languages are influenced by the underlying hardware (e.g., the instruction set of the CPU). Early
languages were closer to machine code; modern languages provide higher levels of abstraction.
Theoretical Foundations: Advances in computer science, like formal semantics and type theory, give language designers powerful
tools to create more reliable and expressive languages.
Efficiency Concerns: The need for language implementations (compilers, interpreters) to be efficient in terms of speed and
.
memory usage impacts design choices.
Practical Considerations
Problem Domains: Languages are often designed with specific problems in mind. For example:
Fortran: Scientific and numerical computation
COBOL: Business applications
JavaScript: Web development
Ease of Learning: Languages intended for beginners generally emphasize simplicity and readability, while those
meant for professionals might prioritize performance or powerful abstractions.
Existing Languages: New languages rarely appear in a vacuum. Designers often draw inspiration from existing
languages, improving upon successes and avoiding past shortcomings.
Influences of Language Design Contd..
Social and Human Factors
Programming Paradigms: Trends and philosophies of how to approach programming problems influence language
design:
Imperative (step-by-step instructions)
Object-Oriented (objects and interactions)
Functional (focus on function composition)
.
Declarative (defining what to achieve, not how)
Programmer Psychology: How programmers think and common errors are considered in language design to
improve readability and reduce bugs.
Communities: The culture and needs of the community surrounding a language can steer its evolution (e.g., open-
source languages often evolve based on user feedback).
Historical Context
Legacy Systems: The need to interact with existing code written in older languages can force some design decisions
in newer ones.
Innovations: Break-through ideas in previous languages often propagate to new ones (e.g., garbage collection from
Lisp became widespread).
Language Categories by Paradigm
A programming paradigm is a fundamental way of thinking about and structuring code. It provides a
set of concepts and principles that guide how you express solutions within a programming language.
Here's a breakdown of the major paradigms:
Imperative Programming
.
Focus: Explicitly instructing the computer on how to modify its state, step by step.
Key concepts:
Objects: Entities with data (attributes) and behaviors (methods).
.
Classes: Blueprints for creating objects.
Inheritance: Creating hierarchies of classes to share behavior.
Polymorphism: Objects of different classes responding to the same message in different ways.
Analogy: Like a system of interacting components, like parts in a car engine working together.
.
Analogy: Like a mathematical equation, where the input uniquely determines the output without any side
effects.
Examples: Haskell, Lisp, Clojure, Erlang, F#
Declarative Programming
Focus: Describing what the program should achieve, without specifying the precise steps how .
Key Concepts:
Logic-based: Expresses rules and constraints (e.g., Prolog)
Query-based: Specifying the desired result of a computation (e.g., SQL)
Analogy: Like ordering a meal and specifying what you want, rather than listing the steps the chef should take.
Examples: SQL, Prolog, HTML, CSS
Language Design Trade off
Functional Programming (FP)
Focus: Problem-solving using the composition of pure functions.
Key concepts:
Functions as first-class entities: Functions can be passed as arguments and returned from other functions.
Immutability: Data is not changed; instead, functions produce new values.
Recursion: Functions that call themselves to solve problems.
Higher-order functions: Functions that operate on other functions.
.
Analogy: Like a mathematical equation, where the input uniquely determines the output without any side
effects.
Examples: Haskell, Lisp, Clojure, Erlang, F#
Declarative Programming
Focus: Describing what the program should achieve, without specifying the precise steps how .
Key Concepts:
Logic-based: Expresses rules and constraints (e.g., Prolog)
Query-based: Specifying the desired result of a computation (e.g., SQL)
Analogy: Like ordering a meal and specifying what you want, rather than listing the steps the chef should take.
Examples: SQL, Prolog, HTML, CSS
Language Design Trade-Offs
• Reliability vs. cost of execution
–Conflicting criteria
–Example: Java demands all references to array elements be checked for proper indexing but that
leads to increased execution costs
• Readability vs. writability
–Another conflicting criteria
–Example: APL provides many powerful operators (and a large number of new symbols), allowing
complex computations to be written in a compact program but at the cost of poor readability
31
Compilation
• Translate high-level program (source language) into machine code (machine
language)
• •Slow translation, fast execution
• •Compilation process has several phases:
–lexical analysis: converts characters in the source program into lexical units
–syntax analysis: transforms lexical units into parse trees which represent the syntactic structure
of the program
–Semantics analysis: generate intermediate code
–code generation: machine code is generated
32
The Compilation Process
33
Pure Interpretation
• No translation
• Easier implementation of programs (run-time errors can easily and
immediately displayed)
• Slower execution (10 to 100 times slower than compiled programs)
• Often requires more space
• Becoming rare on high-level languages
• Significant comeback with some Web scripting languages (e.g.,
JavaScript)
34
Pure Interpretation Process
35
Hybrid Implementation System
• A compromise between compilers and pure interpreters
• A high-level language program is translated to an intermediate language that
allows easy interpretation
• Faster than pure interpretation
• Examples
• Perl programs are partially compiled to detect errors before interpretation
• Initial implementations of Java were hybrid; the intermediate form, byte code, provides
portability to any machine that has a byte code interpreter and a run-time system (together,
these are called Java Virtual Machine)
36
Hybrid Implementation Process
37
Programming Environment
• Programming Environments
• The collection of tools used in software development
• UNIX
• An older operating system and tool collection
• Nowadays often used through a GUI (e.g., CDE, KDE, or GNOME) that
run on top of UNIX
38
Programming Environment
• Borland JBuilder
–An integrated development environment for Java
• Microsoft Visual Studio.NET
–A large, complex visual environment
–Used to program in C#, Visual BASIC.NET, Jscript, J#, or C++
39