Группа авторов

Rethinking Prototyping


Скачать книгу

graph which is the limiting factor. Therefore, what starts off as a useful explanatory tool with five to 20 graph nodes becomes unfathomable with 100 nodes. As the underlying problem increases in complexity, the graph system appears to add visual complexity non-linearly rather than to continue to provide clarity. Essentially an initial advantage of the visual graph representation eventually becomes a limitation.

      Most of the data flow applications allow custom nodes to be implemented using existing high-level languages such as Python or C#. This enables the dataflow system to access external libraries and also allows the designer to implement functionality using imperative programming. This approach is particularly useful where the design logic being implemented might not be suited to data flow programming. However, a second criticism of these applications is that the gap in level of skills required between using a graph-node user interface and using high-level imperative languages is often too extreme for the novice programmers to overcome (Fig. 1).

RobertAish_fig_1.jpg

      Fig. 1 Existing dataflow applications provide an initial ease of use for novice users with simple graph-node models, but do not scale to complex problems. Essentially, there is no continuous learning curve between dataflow diagramming and programming in conventional high-level imperative languages.

      The intention in the development of DesignScript is to address these two issues by providing a single, continuous and gentler learning curve between data flow diagramming and more complex forms of design computation (Fig. 2).

      This learning curve represents a potential progression in skills on the part of designer, his use and understanding of progressively more powerful computational concepts and techniques. Underlying this is also the idea that the designer will be progressing from an exploratory style of programming to more formal software engineering methods, potentially leading to the development of re-usable class libraries.

RobertAish_fig_2.jpg

      Fig. 2 DesignScript introduces a number of intermediate techniques that provide a gentler learning curve for the designer who wants to progress from data flow diagramming to more forms of design computation.

      3 Node to Code

      Node to Code is a feature of DesignScript, which allows the designer to select part or all of a graph-node diagram and have that design logic converted to code. This has two advantages: First, the designer can have his initial design logic presented to him in a code form, so that he can be assisted in progressing from being a graph node user to a more experience scripter. Second, it enables the number of nodes and associated arcs to be reduced in terms of visual complexity. The designer can still make connecting arcs between the variables in the resulting code block (Figs. 3-5).

RobertAish_fig_3.jpg

      Fig. 3 Starting with a conventional graph node diagram ...

RobertAish_fig_4.jpg

      Fig. 4 The designer selects a region of the graph and uses the radial menu [top right]…

RobertAish_fig_5.jpg

      Fig. 5 To turn the nodes into code…

      The key to this ability to convert node to code is that the internal representation of the graph is in fact a script, even though the designer, when using graph- based modelling techniques, may not be aware of this.

      4 Associative Programming

      We define an associative-programming language as the representation of a data flow programme in a human readable textual notation. DesignScript is an associative language, and it has been carefully designed so that where possible it shares the same syntax with imperative languages and only introduces special syntax where necessary.

      Imperative and associative languages share some characteristics, but in other respects diverge.

      The role of different types of statements. In imperative languages there are two types of statements: Executable statements and Flow Control statements, such as for loops to control iteration and if statement to control conditional branching. Executable statements typically define the value of variable, while flow control statements define which statements are executed. In the absence of any flow control, the statements are executed in lexical order, as they appear in the source code. Executable statements are illustrated in following code fragment:

      1. = 10;

      2. = a * 2;

      3. = 20;

      Here in line 2, the value of b is computed based on the pre-existing value of a defined in line 1. As an imperative language, a subsequent change to the value of a (in line 3) has no effect on the value of b.

      In a dataflow application, this logic might be represented in Fig. 6:

      RobertAish_fig_6a.jpg RobertAish_fig_6b.jpg

      Fig. 6a left, the initial graph, and Fig. 6b right, the subsequent state of the graph

      The user does not have to explicitly command that the value of b is recomputed. He expects that having once define the relationship between b and a, that the value of b will be automatically recomputed if the value of a changes.

      The graph, and the user’s interaction with the graph, can be given a corresponding representation in an associative language.

      1. = 10;

      2. = a * 2;

      3. = 20;

      Note, that these statements are exactly the same in both, the imperative and associative languages. However, in an associative language these statements represent more information than the equivalent executable statements in an imperative language because these statements capture the graph dependency as persistent associative relationships. Also there are important differences in execution of the same statements in the two languages.

      Here in line 2, the value of b is computed based on the pre-existing value of a defined in line 1. In associative language (as in the graph), a subsequent change to the value of a (in line 3) will force the computation of the value of b (i.e. the re-execution of line 2) with no additional intervention on the part of the user. In associative languages there are no separate flow control statements. Flow control is defined by the graph dependencies.

      Liveness of the Language: If a change is made to a programme written in most imperative language, then typically the whole programme must be re-complied and re-executed. However, dataflow applications - and therefore related associative languages - are live, in the sense that after initial execution, the programme is maintained in memory so that a change to a variable may only result in a partial re-execution of the programme. Which statements are to be re-executed depends on the persistent associative relationship and the topological ordering of the statements.

      Use of Collections: Associative languages usually provide a way to handle collections using built-in replication techniques. This avoids the user having to write for loops to iterate through collection, and therefore reducing the need for the user to learn about for loops and iteration before using the language.

      The distinction between imperative and associative programming is illustrated by the following example (Figs. 7-8). First, the designer is already completely familiar with imperative programming, then he can program exclusively in an imperative style (Fig. 7).