0% found this document useful (0 votes)
285 views4 pages

Block Structure and Parameter Passing

The document discusses block structured languages and parameter passing mechanisms. It defines block structured languages and notes their introduction in Algol family languages. It also covers parameter passing techniques including call by value, call by reference, call by name and others.

Uploaded by

Musa Jubril
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
285 views4 pages

Block Structure and Parameter Passing

The document discusses block structured languages and parameter passing mechanisms. It defines block structured languages and notes their introduction in Algol family languages. It also covers parameter passing techniques including call by value, call by reference, call by name and others.

Uploaded by

Musa Jubril
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

CSC 218 Foundation of Sequential Program

Lecture Note 4
(Block Structured Languages and Parameter Passing Mechanisms)

Block-structured languages
A class of high-level languages in which a program is made up of blocks – which may
include nested blocks as components, such nesting being repeated to any depth. A block
consists of a sequence of statements and/or blocks, preceded by declarations of
variables. Variables declared at the head of a block are visible throughout the block and
any nested blocks, unless a variable of the same name is declared at the head of an inner
block. In this case the new declaration is effective throughout the inner block, and the
outer declaration becomes effective again at the end of the inner block. Variables are
said to have nested scopes.

The concept of block structure was introduced in the Algol family of languages, and
block-structured languages are sometimes described as Algol-like. The concept of
nested scopes implicit in block structure contrasts with Fortran, where variables are
either local to a program unit (subroutine) or global to several program units if declared
to be COMMON. Both of these contrast with Cobol, where all data items are visible
throughout the entire program.

Properties of an identifier (and the object it represents) may be set at


• Compile-time: These are static properties as they do not change during execution.
Examples include the type of a variable, the value of a constant, the initial value of a
variable, or the body of a function.
• Run-time: These are dynamic properties. Examples include the value of a variable, the
lifetime of a heap object, the value of a function’s parameter, the number of times a
while loop iterates, etc.

Example: In Fortran
• The scope of an identifier is the whole program or subprogram.
• Each identifier may be declared only once.
• Variable declarations may be implicit. (Using an identifier implicitly declares it as a
variable.)
• The lifetime of data objects is the whole program.

Block Structured Languages include Algol 60, Pascal, C and Java.


• Identifiers may have a non-global scope. Declarations may be local to a class,
subprogram or block.
• Scopes may nest, with declarations propagating to inner (contained) scopes.
• The lexically nearest declaration of an identifier is bound to uses of that identifier.

Binding of an identifier to its corresponding declaration is usually static (also called


lexical), though dynamic binding is also possible. Static binding is done prior to
execution—at compile-time. Example (drawn from C):

Parameter Passing Mechanism


In computer programming, a parameter or a formal argument is a special kind
of variable used in a subroutine to refer to one of the pieces of data provided as input to
the subroutine. These pieces of data are the valuesof the arguments (often called actual
arguments or actual parameters) with which the subroutine is going to be
called/invoked. An ordered list of parameters is usually included in the definition of a
subroutine, so that, each time the subroutine is called, its arguments for that call are
evaluated, and the resulting values can be assigned to the corresponding parameters.

Parameter passing allows the values of local variables within a main program to be
accessed, updated and used within multiple sub-programs without the need to create or
use global variables.
The mechanism used to pass parameters to a procedure (subroutine) or function. The
most common methods are to pass the value of the actual parameter (call by value), or
to pass the address of the memory location where the actual parameter is stored (call by
reference). The latter method allows the procedure to change the value of the parameter,
whereas the former method guarantees that the procedure will not change the value of
the parameter. Other more complicated parameter-passing methods have been devised,
notably call by name in Algol 60, where the actual parameter is re-evaluated each time
it is required during execution of the procedure.

Parameter-passing techniques may be broken down as follows:


• Eager evaluation (applicative order) techniques. What these methods have in
common is that the arguments passed in for a function’s parameters are evaluated
before the function is called.
o Call-by-value
o Call-by-reference
o Call-by-copy-restore (also known as value-result or copy-in-copy-out)
• Lazy evaluation (normal order) techniques. What these methods have in common
is that the evaluation of the arguments passed in for a function’s parameters is
delayed until the argument is actually used in the execution of the function.
o Macro expansion
o Call-by-name
o Call-by-need
The difference between call-by-value and call-by-reference is exemplified by the
difference between denoted values in our interpreters for SLang 1 and SLang 2. That is,
in call-by-value, the argument for a function parameter is a copy of the value of the
argument whereas, in call-by-reference, the function is given the address of the
argument. Given the address, the function has the capability of modifying the argument.

Techniques used for argument passing:


• call by value
• call by result
• call by value-result
• call by reference
• call by name
(and call-by-constraint in constraint languages)
call by value: copy going into the procedure
call by result: copy going out of the procedure
call by value result: copy going in, and again going out
call by reference: pass a pointer to the actual parameter, and indirect through the
pointer
call by name: re-evaluate the actual parameter on every use. For actual parameters that
are simple variables, this is the same as call by reference. For actual parameters that are
expressions, the expression is re-evaluated on each access. It should be a runtime error
to assign into a formal parameter passed by name, if the actual parameter is an
expression. Implementation: use anonymous function ("thunk") for call by name
expressions

Common questions

Powered by AI

The 'call-by-name' parameter passing technique re-evaluates the actual parameter every time it is accessed during execution. The advantage of call-by-name is that it defers computation until the expression is needed, which can lead to performance benefits in some scenarios. However, this can also be a disadvantage as it may lead to repeated computations if the parameter is accessed multiple times. A notable issue is that assigning to a formal parameter that is passed by name should be avoided if the actual parameter is an expression, as this may lead to runtime errors .

Nested scopes in block-structured languages allow for a more modular and hierarchical arrangement of code, promoting encapsulation and reuse. This contrasts with languages like Cobol, where all data items are visible throughout the entire program, potentially leading to conflicts and issues with maintaining state across large programs. Nested scopes limit the visibility of variables to the block they are declared in, and potentially inner blocks, which reduces the likelihood of unintended interactions and side effects compared to global scope visibility .

Eager evaluation techniques, such as 'call-by-value' and 'call-by-reference', involve evaluating parameters before a function call is executed, which can simplify the execution flow and reduce overhead at the cost of potentially unnecessary computations. In contrast, lazy evaluation techniques, like 'call-by-name' and 'call-by-need', defer parameter evaluation until the value is actually needed, improving performance in cases where parameters are not always used. However, lazy evaluation can introduce additional complexity in managing and storing computations, and may be less intuitive for developers familiar with imperative evaluation models .

Block-structured languages use a system of nested scopes for variable visibility, where a variable declared in a block is visible within that block and all inner blocks, unless overshadowed by another declaration of the same name in those inner blocks. This contrasts with static binding, which determines variable bindings at compile-time based on lexical structure regardless of execution flow. In static binding scenarios, once an identifier is bound to a declaration, it remains fixed during the execution, usually within a fixed scope determined lexically .

'Call-by-copy-restore', also known as 'call-by-value-result' or 'copy-in-copy-out', combines elements from both 'call-by-value' and 'call-by-reference'. It involves copying the actual parameter's value into the procedure ('copy-in') at the start and then copying the modified value back to the actual parameter ('copy-out') once the procedure finishes. This method is beneficial in scenarios where you want the efficiency of 'call-by-reference' for large data structures, but without allowing the procedure to change the original parameter during execution. It ensures that any changes made within the procedure are reflected outside, but only once the procedure is completed .

Block structured programming languages, such as Algol, Pascal, C, and Java, organize code into blocks that can contain nested blocks. A block consists of a sequence of statements, and it starts with the declaration of variables. Variables declared in a block are visible throughout that block and any nested blocks unless another declaration with the same name exists within a nested block. In such cases, the inner block's declaration takes precedence within that block, while the outer block's declaration is in effect outside it. This nested scope is a contrast to the scope in languages like Fortran, where variables are local to a subprogram or global to several program units if declared as COMMON .

The implementation of 'call-by-name' using thunks is significant because thunks encapsulate the expression to be evaluated, allowing for deferred and repeated execution. By capturing the expression in an anonymous function (or thunk), the evaluation context is preserved, which simplifies delayed evaluations. This approach has implications for language design and efficiency: while it provides flexibility and can optimize resources, it can also add complexity to both implementation and execution, especially if expressions frequently change or involve side effects .

'Call-by-need', an optimization of 'call-by-name', improves program execution efficiency by avoiding repeated evaluations of parameters. Instead of re-evaluating parameters upon every use, 'call-by-need' evaluates the parameter the first time it is needed and caches this result for subsequent uses. This lazy evaluation technique minimizes computation overhead and can lead to significant performance improvements, especially in cases with expensive or resource-intensive calculations .

In block-structured languages, properties of an identifier can be either static or dynamic. Static properties are defined at compile-time and remain unchanged during execution, such as the type of a variable or the body of a function. Dynamic properties, however, are determined at run-time and include the current value of a variable or the number of iterations a loop executes. Static properties are related to the lexical scoping of variables, whereas dynamic properties are often associated with the program's run-time behavior .

In 'call by value', the actual parameter's value is copied and passed to the function, meaning changes to the parameter within the function do not affect the original argument. In 'call by reference', instead of copying, a reference or address of the actual parameter is passed, allowing the function to modify the original argument. The fundamental difference lies in the ability of the function to alter the original data: 'call by reference' allows this, while 'call by value' does not .

You might also like