Skip to content

Instantly share code, notes, and snippets.

@jki127
Last active December 18, 2019 04:08
Show Gist options
  • Save jki127/3010a66a4ff5794a79cbb52930ae62f1 to your computer and use it in GitHub Desktop.
Save jki127/3010a66a4ff5794a79cbb52930ae62f1 to your computer and use it in GitHub Desktop.

Partial Functions, Blocks, Scope, Lifetime, & Memory Allocation - Programming Languages - Sept 17th, 2019

Partial Functions - Haskell

Similar to mathematics, not every input needs to have an output. For example, the code below does not have a return value when given an empty list

mylast :: [a] -> a
-- mylast [] = []
mylast [x] = x
mylast (x : xs) = mylast xs

Blocks

Variables are usually defined in blocks, but can also be defined in:

  • the global scope
  • namespaces
  • structs
int x;

namespace Foo {
	int qwaptu = 4;
}

struct Whatever {
	string z;
}

int foo(){ // first block
	int x = 3;
	while (x > 0) { // second block 
		x-=1
	}
}

Scope

The region of a program over which a binding is maintained

What will be printed in the following C++ code?

Code 1.1

int x = 3;
void foo() {
	print(x);
	x = 9;
}

int main() {
	int x = 0; // shadow
	foo();
	print(x);
	return 0;
}
Answer 3 and 0

When two variables with same name are defined in overlapping scopes, then one variables shadows another variable.

In C++, we could refer to the global x by writing ::x. :: is the scope operator in C++.

Static Scoping (Lexical)

C++, C, Python, and Java use static scoping which means you know the scope of your variables and functions before you run your program

Dynamic Scoping

Functions have the same scope as where they were called from. Dynamic Scoping is almost like copying and pasting the body of a function wherever it is called.

What would the same code from before print if it was using dynamic scoping?

Answer: 0 and 9
int x = 3;
void foo() {
	print(x);
	x = 9;
}

int main() {
	int x = 0; // shadow
	foo();
	print(x);
	return 0;
}

Harder Example (Good Exam Question πŸ˜‰)

#include <stdio.h>

int x = 1;
char y = 'a';
void p() {
	double x = 2.5;
	printf("%c \n", y);
	{ int y[10]; }
}

void q() {
	int y = 42;
	printf("%d \n", x);
	p();
}

main() {
	char x = 'b';
	q();
	return 0;
}

What does this program print if you are using Static Scoping?

Answer: 1 and β€˜a’

What does this program print if you are using Dynamic Scoping?

Answer: 98 and '*'
This is because the `printf` statements include conversions between char and double.

Lifetime of a Variable & Memory Allocation

int main(){
	int *x = new int(0);
	delete x;
	return 0;
}

Lifetime: the duration for which a variable has memory allocated for it

Types of Memory Allocation:

  • Automatic (Stack) Allocation
    • defining a variable inside a function
  • Dynamic Allocation
    • ex: using new in C++
  • Static Allocation
    • ex: global variable
    • In C++, you can define a variable with the keyword static inside a function as well
      • The lifetime of a static variable is the same as a global variable
      • The scope of the static variable is still local

Static in C++

void incprint() {
	static int x = 0;
	print (x);
	x++;
}

int main(){
	incprint(); // prints 1
	incprint(); // prints 2 
	incprint(); // prints 3
	return 0;
}

What does this program print?

int *bar() {
	int i = 99;
	return &i;
}
int main() {
	int *z = bar();
	print(*z);
	return 0;
}
Answer:
This program has a bug because you are trying to print `i` which now points to a deallocated space in memory

Another Example

int x = 3;

void barf() {
	int c;
	foo();
}

void foo() {
	print(x);
	x = 9;
}

int main() {
	foo();
	int x = 0;
	barf();
	print(x);
	return 0;
}

#proglang-f19

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment