Changes between Version 3 and Version 4 of PIL


Ignore:
Timestamp:
10/03/24 16:06:01 (20 months ago)
Author:
siegel
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • PIL

    v3 v4  
    4444- Type definitions: `typedef typename ID;`
    4545
     46== Functions
     47
     48There are two kinds of functions in PIL:
     491. Imperative functions = "procedures"
     501. Logic functions
     51
     52=== Procedures
     53
     54Like in C.  These can be nested.  Obviously they can have side-effects, be nondeterministic, and the behavior can depend on non-local state.  A procedure call `f(x1,...,xn)` is an expression that can be used anywhere an expression with side-effects is allowed.  Imperative procedures are not values and cannot be assigned to anything.  However, as in C, a pointer to a procedure is a first-class value that can be assigned, used as an argument, returned, etc.   There is a procedure type, exactly like C's function type, e.g.,
     55{{{
     56       typedef int(int) i2i;
     57}}}
     58defines `i2i` to be the type "procedure consuming int and returning int".  Most commonly, pointers to procedure types will be used, e.g.,
     59{{{
     60       typedef int(int)* i2ip;
     61}}}
     62defines the type "pointer to procedure from int to int".  As in C, a pointer to a procedure can be used in a procedure call.
     63
     64A procedure definition can be templated:
     65{{{     
     66       <T1,T2,...> <procedure def>
     67}}}   
     68This defines one procedure for each assignment of types to the Ti.
     69     
     70=== Logic functions
     71
     72Typically specified by a $lambda expression. These are first-class objects in PIL: they can be assigned to variables, passed as an argument in a function call (including a procedure call), and can be returned by a function.  Each has a type of the form `$fun<U,T1,...,Tn>` (functions from `T1` x ... x `Tn` to `U`).  They are side-effect-free.  An application of a logic function `f(x1,...,xn)` is an expression that can be used anywhere an expression is allowed.  A logic function is not necessarily pure, i.e., the value of an application may depend on any part of the state, not just the arguments.
     73 
     74=== Lambda expressions
     75
     76There are two kinds of lambda expressions.  The first kind defines a procedure, the second a logical function.
     77
     78Procedural lambda syntax:
     79{{{
     80  $lambda [U1 v1=init1; ... Um vm=initm;] R (T1 x1, ..., Tn xn) { S1; ... }
     81}}}
     82where
     83* the `Ti` and `Uj` are types
     84* the `xi` and `vj` are variables
     85* R is a type (the return type), which may be void
     86* {S1; ...} is a block (same as in function definition)
     87* the only variables that can occur free in the block are the xi and vj
     88* if R is not void, the block must return a value of type R
     89
     90The type of this expression is `R(T1, ..., Tn)`.
     91
     92Logic function lambda syntax:
     93{{{
     94  $lambda [U1 v1=init1; ... Um vm=initm;] R (T1 x1, ..., Tn xn) expr
     95}}}
     96where
     97* the `Ti` and `Uj` are types
     98* the `xi` and `vj` are variables
     99* R is a type (the return type), which cannot be void
     100* `expr` is a side-effect-free expression of type R
     101* the only variables that can occur free in `expr` are the xi and vj
     102
     103The type of this expression is `$fun<R, T1, ..., Tn>`.
     104
     105In both cases, the initializer expressions `initj` are expressions using any variables in scope.
     106
     107==== Semantics
     108
     109FIX THIS:  difference between logic and procedural functions...
     110
     111
     112
     113The lambda expression is evaluated to yield a *closure*:  an ordered pair consisting of a dyscope and an expression.  The dyscope has variables `v1`, ..., `vm`, initialized by evaluating `init1`, ..., `initm`.  The dyscope has no parent scope, it is associated only with the closure.  The expression is `expr`.  The dyscope is destroyed whenever it becomes unreachable, i.e., whenever no part of the state is assigned the closure.
     114
     115A logic function application `f(e1,...,en)` is evaluated by first evaluating the arguments `ei`, then assigning the `ei` to the `xi` and evaluating expr in the closure dyscope.  Note that since expr has no side effects, the values of the xi are constant.  [Note: a possible change is to allow side-effects in logic functions.]
     116
    46117== Tuples
    47118
     
    125196- `void $map_addAll($map<K,V> * this, $map<K,V> that);`
    126197
    127 == Functions
    128 
    129 There are two kinds of functions in PIL:
    130 1. (Imperative) procedures
    131 1. Logic functions
    132 
    133 === Procedures
    134 
    135 Like in C.  These can be nested.  Obviously they can have side-effects, be nondeterministic, and the behavior can depend on non-local state.  A procedure call `f(x1,...,xn)` is an expression that can be used anywhere an expression with side-effects is allowed.  Imperative procedures are not values and cannot be assigned to anything.  However, as in C, a pointer to a procedure is a first-class value that can be assigned, used as an argument, returned, etc.   There is a procedure type, exactly like C's function type, e.g.,
    136 {{{
    137        typedef int(int) i2i;
    138 }}}
    139 defines `i2i` to be the type "procedure consuming int and returning int".  Most commonly, pointers to procedure types will be used, e.g.,
    140 {{{
    141        typedef int(int)* i2ip;
    142 }}}
    143 defines the type "pointer to procedure from int to int".  As in C, a pointer to a procedure can be used in a procedure call.
    144 
    145 A procedure definition can be templated:
    146 {{{     
    147        <T1,T2,...> <procedure def>
    148 }}}   
    149 This defines one procedure for each assignment of types to the Ti.
    150      
    151 === Logic functions
    152 
    153 Typically specified by a $lambda expression. These are first-class objects in PIL: they can be assigned to variables, passed as an argument in a function call (including a procedure call), and can be returned by a function.  Each has a type of the form `$fun<T1,...,Tn;U>` (functions from `T1` x ... x `Tn` to `U`).  They are side-effect-free.  An application of a logic function `f(x1,...,xn)` is an expression that can be used anywhere an expression is allowed.  A logic function is not necessarily pure, i.e., the value of an application may depend on any part of the state, not just the arguments.
    154  
    155 === Lambda expressions
    156 
    157 There are two kinds of lambda expressions.  The first kind defines a procedure, the second a logical function.
    158 
    159 Procedural lambda syntax:
    160 {{{
    161   $lambda [U1 v1=init1; ... Um vm=initm;] R (T1 x1, ..., Tn xn) { S1; ... }
    162 }}}
    163 where
    164 * the `Ti` and `Uj` are types
    165 * the `xi` and `vj` are variables
    166 * R is a type (the return type), which may be void
    167 * {S1; ...} is a block (same as in function definition)
    168 * the only variables that can occur free in the block are the xi and vj
    169 * if R is not void, the block must return a value of type R
    170 
    171 The type of this expression is `R(T1, ..., Tn)`.
    172 
    173 Logic function lambda syntax:
    174 {{{
    175   $lambda [U1 v1=init1; ... Um vm=initm;] R (T1 x1, ..., Tn xn) expr
    176 }}}
    177 where
    178 * the `Ti` and `Uj` are types
    179 * the `xi` and `vj` are variables
    180 * R is a type (the return type), which cannot be void
    181 * `expr` is a side-effect-free expression of type R
    182 * the only variables that can occur free in `expr` are the xi and vj
    183 
    184 The type of this expression is `$fun<R, T1, ..., Tn>`.
    185 
    186 In both cases, the initializer expressions `initj` are expressions using any variables in scope.
    187 
    188 ==== Semantics
    189 
    190 FIX THIS:  difference between logic and procedural functions...
    191 
    192 
    193 
    194 The lambda expression is evaluated to yield a *closure*:  an ordered pair consisting of a dyscope and an expression.  The dyscope has variables `v1`, ..., `vm`, initialized by evaluating `init1`, ..., `initm`.  The dyscope has no parent scope, it is associated only with the closure.  The expression is `expr`.  The dyscope is destroyed whenever it becomes unreachable, i.e., whenever no part of the state is assigned the closure.
    195 
    196 A logic function application `f(e1,...,en)` is evaluated by first evaluating the arguments `ei`, then assigning the `ei` to the `xi` and evaluating expr in the closure dyscope.  Note that since expr has no side effects, the values of the xi are constant.  [Note: a possible change is to allow side-effects in logic functions.]
    197198
    198199== Heaps