Richard Urwin wrote:
Have you considered that OpenSCAD is to all external purposes a Data Flow
language that bears striking similarities to languages such as SISAL? (In
fact making OpenSCAD more like SISAL would be wonderful -- there's more
orthogonality and more powerful structures there,
I'm wondering what it would mean to "make OpenSCAD more like SISAL".
Wikipedia describes SISAL as a "single assignment functional programming
language with strict semantics", and that also describes OpenSCAD.
We've had discussions in the past about making OpenSCAD more like a
functional language. This would entail making functions, modules and
geometric shapes into first class values. We could also add pattern
matching, a module system (namespaces) and a record type.
But you said Data Flow language, not functional language. I have no
experience with data flow languages, and I wonder how they are different
from functional languages? As far as I can tell, the language feature that
distinguishes SISAL as a data flow language is the loop syntax,
specifically the "for" expression.
I don't know anything about how OpenSCAD works internally, but it seems to me
that you need to generate a tree of objects to be created. A functional
programming language can be represented as such a tree and is therefore a
good fit to your needs. However you have other needs that are not well
represented by the functional model. For example is in not required that a
functional program is parallelizable but such would be of great use to
OpenSCAD with its extended execution time and the prelevence of
multiple-processor architectures. Language structures that OpenSCAD needs
such as the union and difference constructs with their code bodies bend the
functional paradigm. (They are special case lambda expressions but the user
cannot create such things.) OpenSCAD's dependence on recursion to support
certain programming needs creates a barrier to entry for newbies and an
optimization issue for developers. Other functional languages either provide
structures that bend the functional paradigm or put major effort into
optimization. Neither of which approaches solve both of the issues that
OpenSCAD has.
A Data Flow language represents its program as a directed graph of
operations. The nodes represent operations and the edges between nodes
represent variables.
http://forum.openscad.org/file/n18526/graph.png
The graph on the left represents the program:
A = 2;
B = 3;
C = 5;
D = 1.2;
cylinder(r=A+B, h=CD);
When a node has all the inputs it needs it is free to execute. So the values
2 and 3 flow to the "+" node which then executes and passes the "radius"
value to the "cylinder" node. Simultaneously, the "" node receives its
inputs and also executes, passing the result to the "cylinder" node as its
"height" argument. The "cylinder" node now has all of its data and can
execute in its turn.
A data-flow program is inherently parallelizable on common-memory
multi-processor architectures; the graph can be partitioned easily. But to
maintain that flexibility it has precisely the same requirement that
OpenSCAD has that variables don't change etc.
The graph on the right is for the example in the OpenSCAD README:
union() {
cylinder(h = 30, r = 8);
translate([0, 0, 40]) sphere(20);
}
I imagine that this is identical to the tree that OpenSCAD produces for the
same code, maybe with more nodes and you may be more used to seeing it
upside-down. The Data Flow representation is precisely the same as the tree
form that OpenSCAD requires. Even if their execution dynamics are different,
their needs coincide. Which is why I said that "OpenSCAD is to all
external purposes a Data Flow language".
SISAL offers a richer programming environment than OpenSCAD. It has
aggregate data types and more powerful array handling in addition to its for
loops which provide an alternative to recursion in most cases. It is an old
language with an out-dated syntax however it has solved many of the issues
that OpenSCAD has still to address. An investigation into its source code
may benefit OpenSCAD. (There's a modern implementation on SourceForge.)
In addition, the redefinition of OpenSCAD as a data flow language could
clean up its syntax in other ways, such as the removal of unnecessary
parentheses on union, difference and for statements. Adopting SISAL's
approach of everything being an expression rather than everything being a
function would allow clearer syntax such as an if statement rather than the
?: trinary. The somewhat odd structures in OpenSCAD where a function
invocation (such as union) has a code body would make sense. Such changes
could easily be made backwards compatible.
In summary, a data-flow paradigm fits OpenSCAD's requirements better than a
functional model does and there are resources out there that would benefit
the OpenSCAD project.
--
View this message in context: http://forum.openscad.org/OpenSCAD-and-data-flow-languages-tp18521p18526.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Thanks for the detailed response, Richard. Some good ideas to think about.
On 4 October 2016 at 06:17, Richard Urwin soronlin+openscad@googlemail.com
wrote:
I don't know anything about how OpenSCAD works internally, but it seems to
me
that you need to generate a tree of objects to be created. A functional
programming language can be represented as such a tree and is therefore a
good fit to your needs. However you have other needs that are not well
represented by the functional model. For example is in not required that a
functional program is parallelizable but such would be of great use to
OpenSCAD with its extended execution time and the prelevence of
multiple-processor architectures. Language structures that OpenSCAD needs
such as the union and difference constructs with their code bodies bend the
functional paradigm. (They are special case lambda expressions but the user
cannot create such things.) OpenSCAD's dependence on recursion to support
certain programming needs creates a barrier to entry for newbies and an
optimization issue for developers. Other functional languages either
provide
structures that bend the functional paradigm or put major effort into
optimization. Neither of which approaches solve both of the issues that
OpenSCAD has.
A Data Flow language represents its program as a directed graph of
operations. The nodes represent operations and the edges between nodes
represent variables.
http://forum.openscad.org/file/n18526/graph.png
The graph on the left represents the program:
A = 2;
B = 3;
C = 5;
D = 1.2;
cylinder(r=A+B, h=CD);
When a node has all the inputs it needs it is free to execute. So the
values
2 and 3 flow to the "+" node which then executes and passes the "radius"
value to the "cylinder" node. Simultaneously, the "" node receives its
inputs and also executes, passing the result to the "cylinder" node as its
"height" argument. The "cylinder" node now has all of its data and can
execute in its turn.
A data-flow program is inherently parallelizable on common-memory
multi-processor architectures; the graph can be partitioned easily. But to
maintain that flexibility it has precisely the same requirement that
OpenSCAD has that variables don't change etc.
The graph on the right is for the example in the OpenSCAD README:
union() {
cylinder(h = 30, r = 8);
translate([0, 0, 40]) sphere(20);
}
I imagine that this is identical to the tree that OpenSCAD produces for the
same code, maybe with more nodes and you may be more used to seeing it
upside-down. The Data Flow representation is precisely the same as the tree
form that OpenSCAD requires. Even if their execution dynamics are
different,
their needs coincide. Which is why I said that "OpenSCAD is to all
external purposes a Data Flow language".
SISAL offers a richer programming environment than OpenSCAD. It has
aggregate data types and more powerful array handling in addition to its
for
loops which provide an alternative to recursion in most cases. It is an old
language with an out-dated syntax however it has solved many of the issues
that OpenSCAD has still to address. An investigation into its source code
may benefit OpenSCAD. (There's a modern implementation on SourceForge.)
In addition, the redefinition of OpenSCAD as a data flow language could
clean up its syntax in other ways, such as the removal of unnecessary
parentheses on union, difference and for statements. Adopting SISAL's
approach of everything being an expression rather than everything being a
function would allow clearer syntax such as an if statement rather than the
?: trinary. The somewhat odd structures in OpenSCAD where a function
invocation (such as union) has a code body would make sense. Such changes
could easily be made backwards compatible.
In summary, a data-flow paradigm fits OpenSCAD's requirements better than a
functional model does and there are resources out there that would benefit
the OpenSCAD project.
--
View this message in context: http://forum.openscad.org/
OpenSCAD-and-data-flow-languages-tp18521p18526.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Rather than tie up the Plogon thread any more, I'll drop this here.
I was considering for loops and functional language last night.
Consider:
What about adding some more parameter passing like this:
Then we need a little more syntax:
for x in list
initially
{
y = 0
}
{
y = old y + 1
...
}
"y" refers to the parameter that is to be handed off to the next recursion
and "old y" refers to the parameter that was passed to this recursion.
--
View this message in context: http://forum.openscad.org/OpenSCAD-and-data-flow-languages-tp18521p18797.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
(mailing list still doesn't like raw text.)
Rather than tie up the Polygon thread any more, I'll drop this here.
I was considering for loops and functional language last night.
Consider:
for x in list
body
That can be seen as an anonymous function something like:
function anon(list)
{
if len(list) > 0 then
{
x = head(list)
body
anon(tail(list));
}
}
anon(list);
What about adding some more parameter passing like this:
function anon(list, local definitions)
{
if len(list) > 0 then
{
x = head(list)
body
anon(tail(list), local definitions);
}
}
anon(list, initial definitions);
Then we need a little more syntax:
for x in list
initially
{
y = 0
}
{
y = old y + 1
...
}
"y" refers to the parameter that is to be handed off to the next recursion
and "old y" refers to the parameter that was passed to this recursion.
So that would convert to:
function anon(list, old_y)
{
if len(list) > 0 then
{
x = head(list)
y = old_y + 1
...
anon(tail(list), y);
}
}
anon (list, 0);
--
View this message in context: http://forum.openscad.org/OpenSCAD-and-data-flow-languages-tp18521p18798.html
Sent from the OpenSCAD mailing list archive at Nabble.com.