From 30c185deaf4ed133a1553f66fbfe320badb417f4 Mon Sep 17 00:00:00 2001 From: Henrik Tidefelt Date: Sun, 5 Jul 2009 02:37:34 +0200 Subject: [PATCH] Examples: Removed procedures and updated to work under new analysis. At the moment, the new analysis causes some new problems when an insertion sequence (or any other expression resulting in THE_SLOT_VARIABLE) is used as argument expression in a function call. The function will think that the argument is missing. --- examples/features/amb.shape | 2 +- examples/features/states.shape | 82 +++--------------------------------------- examples/features/values.shape | 18 +++++----- 3 files changed, 15 insertions(+), 87 deletions(-) diff --git a/examples/features/amb.shape b/examples/features/amb.shape index 271a813b..5344faa1 100644 --- a/examples/features/amb.shape +++ b/examples/features/amb.shape @@ -119,7 +119,7 @@ terms: **/ •stdout << `Numbers that sum to four, the second not being bigger than the first:´ [foldsl - \ •dst p e → { •dst << ` ´ << e[]'0 << `+´ << e[]'1 } + \ •dst p e → { •dst << ` ´ << e[]'0 << `+´ << e[]'1 p } void •stdout terms] diff --git a/examples/features/states.shape b/examples/features/states.shape index 21034230..f4d6bcb8 100644 --- a/examples/features/states.shape +++ b/examples/features/states.shape @@ -53,11 +53,10 @@ str: •str; /** Next, we turn to the scoping rules for lexical access of states. The rule is that states ** cannot be accessed across function boundaries. This makes functions behave as functions. - ** The language also provides procedures, which are like functions without boundaries. Procedures - ** do not behave as functions, but may be used internally in functions as long as they don't - ** reach for states outside the function boundary. - ** Note that procedures are called with a special syntax, so that it is obvious that the calls - ** cannot be delayed. + ** + ** Versions of Shapes up to 0.5.0 also had procedures which did not have the "function boundary", + ** and which had to be called using special syntax. However, these have been removed to make + ** programs easier to understand. **/ /** Let's begin with a legal program. @@ -65,13 +64,7 @@ str: •str; fun: \ a → { •s: newString - proc: \ b → ! - { - /** Note that, for instance, •stdout is not in scope here. - **/ - •s << b << a << b - } - [!proc `Hej!´] + •s << a << `Hey!´ << a •s; } @@ -88,32 +81,6 @@ fun: \ a → |** } -/** The following would also be illegal, since the procedure must be applied in - ** an environment being the same or a child to the procedure's environment. - ** However, while the illegal situation in the program above can always be detected - ** during the analysis pass, the problem here is basically something which needs to - ** be detected runtime. Hence, just defining badFun may leave the error undetected - ** (although this situation would actually be quite easy to recognize during the - ** analysis pass). - **/ -globalProc: \ msg → ! { •stdout << msg << "{n} } -|** badFun: \ a → -|** { -|** [!globalProc a] -|** a + ` so bad!´ -|** } -|** •stdout << [badFun `I'm bad!´] << "{n} - -/** As a last example of procedures, the following program is legal! - ** Note that the difference is that goodProc is a procedure, so it should be OK - ** to modify •stdout from within its body. - **/ -goodProc: \ a → ! -{ - [!globalProc a] -} -[!globalProc `This program is OK.´] - /** States may also be passed to functions. Functions that take states as arguments are like ** macros in that their evaluation cannot be delayed. However, since the states being modified ** are explicitly passed to the function, the code is much easier to understand than code that @@ -127,42 +94,3 @@ goodProc: \ a → ! dummyStroke: \ •dst2D → { •dst2D << [stroke (0cm,0cm)--(1cm,1cm)] } [dummyStroke •page] - - -/** We finally take a look at dynamic states. This is a tricky topic, and a mechanism that - ** is recommended to stay away from as much as possible. - ** To get reasonable semantics for this beast, we are required to make runtime checks that - ** the accessed states are indeed in dynamic scope, and this makes them more expensive to - ** use compared to dynamic variables. - **/ - -/** In fact, at the time of writing, dynamic states are not even implemented, but the following - ** is a guess of what the final design might look like in use. - **/ - -•dst1: newString -•dst2: newString - -•dst1 << `1:´ -•dst2 << `2:´ - -say_y: \ •dstStr → { •dstStr << `y´ } - -|** dynamic @•dfoo •stdout -|** -|** foo: \ → ! -|** { -|** @•dfoo << ` x ´ -|** [say_y @•dfoo] -|** } -|** -|** @•dfoo: •dst1 -|** | [! foo] -|** -|** @•dfoo: •dst2 -|** | [! foo] -|** -|** @•dfoo: •dst1 -|** | [! foo] - -|** •stdout << (•dst1) << "{n} << (•dst2) << "{n} diff --git a/examples/features/values.shape b/examples/features/values.shape index 85318b3a..7cab43e1 100644 --- a/examples/features/values.shape +++ b/examples/features/values.shape @@ -84,31 +84,31 @@ ** of view, so code that wish to be type-compilant should not use sinks. **/ { - foo: \ <> args → ! + foo: \ •out <> args → { - •stdout << `a = ´ << args.a << `, b = ´ << args.b << "{n} + •out << `a = ´ << args.a << `, b = ´ << args.b << "{n} } - [!foo b:2 a:1] + [foo •stdout b:2 a:1] - bar: \ a <> args → ! + bar: \ •out a <> args → { - •stdout << `a = ´ << a << `, b = ´ << args.b << `, c = ´ << args.c << "{n} + •out << `a = ´ << a << `, b = ´ << args.b << `, c = ´ << args.c << "{n} } - [!bar 0 c:2 b:1] + [bar •stdout 0 c:2 b:1] /** Sinks themselves cannot be passed as a named argument. Hence, the name of the sink can be used without ** confusion: **/ - boo: \ <> args → ! + boo: \ •out <> args → { - •stdout << `args = ´ << args.args << "{n} + •out << `args = ´ << args.args << "{n} } - [!boo args:7] + [boo •stdout args:7] } /** Next, we turn to how parts of a structure can conveniently be given names in the local scope. -- 2.11.4.GIT