various languages…. nested methods lexical (static) vs. dynamic scope referencing environments ...

29
More High-Level Concepts various languages…

Upload: camilla-gregory

Post on 25-Dec-2015

233 views

Category:

Documents


0 download

TRANSCRIPT

  • Slide 1
  • various languages
  • Slide 2
  • Nested methods Lexical (static) vs. Dynamic Scope Referencing Environments Some examples from Clojure and Ruby Union Types Ada compare to classes Coroutines
  • Slide 3
  • Nested Subprograms Not allowed in C and descendants Allowed in Algol 68, Pascal, Ada More recently included in JavaScript and Python What about Ruby? Not really (interesting example coming up)
  • Slide 4
  • The scope of a variable is the range of statements over which it is visible The nonlocal variables of a program unit are those that are visible but not declared there Static scoping: Algol, Pascal, C-type, Ruby Dynamic scoping: Bash Programmer choice: Perl, Lisp
  • Slide 5
  • 1-5 Static Scope (aka lexical scope) procedure Big is X : Integer; procedure Sub1 is X : Integer; begin... end; procedure Sub2 is begin..X.. end; begin // Big... end; Reference to X in Sub2 refers to X in static parent Big. The X in Sub1 is not a static ancestor of Sub2. Scope of Sub1 Scope of Sub2 Scope of Big C & C++ do not allow nested procedures. Nor does Java. Inner classes may accomplish some of same goals Based on program text Search declarations, first locally, then in increasingly larger enclosing scopes Dont confuse static scope with static lifetime! What languages use static scope? Pascal, Ada, ML, Haskell
  • Slide 6
  • Scope (continued) Variables can be hidden from a unit by having a "closer" variable with the same name int count; while (...) { int count;... } illegal in Java and C#, legal in C and C++ C++ and Ada allow access to these "hidden" variables In Ada: unit.name In C++: class_name::name, ::name for global Notice that blocks also create static scopes Scope resolution operator
  • Slide 7
  • Dynamic Scope Based on calling sequences of program units, not their textual layout temporal versus spatial References to variables are connected to declarations by searching back through the chain of subprogram calls that forced execution to this point. Must be determined at runtime.
  • Slide 8
  • Example from Sebesta: Principles of Programming Languages Scope Example MAIN declaration of x SUB1 declaration of x... call SUB2... SUB2... reference to x...... main body MAIN calls SUB1 SUB1 calls SUB2 SUB2 uses x ---- declared in SUB1 MAIN calls SUB2 SUB2 uses x ----- declared in MAIN Static scoping Reference to x in SUB2 is to MAIN's x Dynamic scoping Reference to x depends on call sequence
  • Slide 9
  • var y = "global"; function print-y() { print(y); } function test-scope() { var y = "local"; print-y(); } test-scope(); // static languages print "global" // dynamic languages print "local" print-y(); // all languages should print "global"
  • Slide 10
  • Referencing Environments The referencing environment of a statement is the collection of all names that are visible in the statement In a static-scoped language local variables plus all of the visible variables in all of the enclosing scopes In a dynamic-scoped language local variables plus all visible variables in all active subprograms Referencing Environment concept is important because data structures must be created to provide access to all nonlocal variables Future topic: closures
  • Slide 11
  • Example from Sebesta: Principles of Programming Languages Referencing Environments Static Example procedure Example is A, B : Integer;... procedure Sub1 is X, Y : Integer; begin #a... end; procedure Sub2 is X : Integer;... procedure Sub3 is X : Integer; begin - #b end; begin - #c end; // Sub2 begin -... #d end. Point a env: X and Y of Sub1, A and B of Example Point b env: X of Sub3 (X of Sub2 is hidden), A and B of Example Point c env: X of Sub2, A and B of Example Point d env: A and B of Example
  • Slide 12
  • Referencing Environments Dynamic Example void sub1() { int a, b; #X } void sub2() { int b, c; #Y sub1; } int main() { int c, d; #Z sub2(); } Assume main calls sub2, which calls sub1: Point #X env: a and b of sub1 c of sub2 d of main (c of main and b of sub2 are hidden) Point #Y env: b and c of sub2 d of main (c of main hidden) Point #Z env: c and d of main Well do a scoping exercise Example from Sebesta: Principles of Programming Languages
  • Slide 13
  • Uses the binding macro Suggested uses debug function calls by dynamically overriding that function to print every time it gets called The clojure/java.jdbc library uses a dynamic var *db* so that you don't have to pass in a database connection to every function call. You can just use the with-connection macro to bind *db* to the database you want to use, and then perform any database queries within the body of the macro. It allows you to mock functions that have side-effects to make them more unit-testable. From: http://blog.rjmetrics.com/lexical-vs-dynamic-scope-in-clojure/
  • Slide 14
  • A very useful application of dynamic scoping is for passing contextual parameters without having to add new parameters explicitly to every function in a call stack (defn do-stuff [] (do-other-stuff) (print "stuff done!")) (binding [*out* my-debug-output-writer] (do-stuff)) From: http://programmers.stackexchange.com/questions/103164/when-would-dynamic-scoping-be-useful
  • Slide 15
  • Ruby allows access to current variable bindings via Kernel#binding
  • Slide 16
  • class Largeco class Person def hello # notice definitions inside hello def hi "hello" end def bye "goodbye" end #notice call to hi hi end # of hello definition def hi "hi" end def bye "bye-bye" end end # end Person class end # end Largeco class puts "Scott and Mark are casual" scott = Largeco::Person.new mark = Largeco::Person.new puts "Scott says: #{scott.hi}" puts "Mark says: #{mark.hi}" puts "Scott says: #{scott.bye}" puts "Mark says: #{mark.bye}" puts "\nBUT Chris is formal, everyone must respond in kind" chris = Largeco::Person.new puts "Chris says: #{chris.hello}" puts "Scott says: #{scott.hi}" puts "Chris says: #{chris.bye}" puts "Scott says: #{scott.bye}" Example (not recommended) from https://gist.github.com/markmcspadden/1322598 Quick Ex: Trace this!
  • Slide 17
  • def test_outer( a, b ) def test_inner( a ) puts "#{a} and #{b}" end test_inner( a+b ) end # test_outer test_outer( 1, 2 ) Result: b is undefined http://www.justskins.com/forums/nested-methods-and-scope-198687.html
  • Slide 18
  • def toggle puts "subsequent" end puts "first" end toggle Output: first subsequent Why? Explain to your partner why are these not nested methods?
  • Slide 19
  • Unions Types A union is a type whose variables are allowed to store different type values at different times during execution Example: flex/bison. Lexer needs to pass values to the parser. Flex/Bison (lex/yacc) uses a memory location that both programs know. BUT, value passed may be string, int, float, etc. Use a UNION to handle.
  • Slide 20
  • C Union union flexType { int intEl; float floatEl; } el1; float x; int y;... el1.intEl = 27; y = el1.intEl; x = el1.floatEl; // nonsense Is this the same as Rubys dynamic types? Why/why not?
  • Slide 21
  • Discriminated vs. Free Unions Fortran, C, and C++ provide union constructs in which there is no language support for type checking; the union in these languages is called free union Type checking of unions require that each union include a type indicator called a discriminant Supported by Ada
  • Slide 22
  • Ada Union Types type Shape is (Circle, Triangle, Rectangle); type Colors is (Red, Green, Blue); type Figure (Form: Shape) is record Filled: Boolean; Color: Colors; case Form is when Circle => Diameter: Float; when Triangle => Leftside, Rightside: Integer; Angle: Float; when Rectangle => Side1, Side2: Integer; end case; end record;
  • Slide 23
  • Ada Union Type Illustrated A discriminated union of three shape variables
  • Slide 24
  • Evaluation of Unions Potentially unsafe construct Do not allow type checking Java and C# do not support unions Reflective of growing concerns for safety in programming language http://stackoverflow.com/questions/565 3678/union-types-and-intersection-types http://stackoverflow.com/questions/565 3678/union-types-and-intersection-types
  • Slide 25
  • Coroutines A coroutine is a subprogram that has multiple entries and controls them itself (maintain status) Also called symmetric control: caller and called coroutines are on a more equal basis A coroutine call is named a resume The first resume of a coroutine is to its beginning, but subsequent calls enter at the point just after the last executed statement in the coroutine Coroutines repeatedly resume each other, possibly forever Coroutines provide quasi-concurrent execution of program units (the coroutines); their execution is interleaved, but not overlapped Information from: Programming Languages, Sebesta
  • Slide 26
  • Copyright 2006 Addison-Wesley. All rights reserved. Coroutines Illustrated: Possible Execution Controls
  • Slide 27
  • Copyright 2006 Addison-Wesley. All rights reserved. Coroutines Illustrated: Possible Execution Controls
  • Slide 28
  • Copyright 2006 Addison-Wesley. All rights reserved. Coroutines Illustrated: Possible Execution Controls with Loops
  • Slide 29
  • Coroutines (cont) Coroutines originated as an assembly- language technique Supported in some high-level languages, Simula and Modula-2 being two early examples. Coroutines are well-suited for implementing more familiar program components such as cooperative tasks, iterators, infinite lists, and pipes (per Wikipedia)