When OpenSCAD got equipped with List Comprehension, the compiler-enforced
prohibition against true variables fell by the wayside. A list may be used
as the foundation of a user-controlled memory system. Consider this code:
// create list
FirstList=[for (i=[0:1:6]) i];
LastOne=FirstList[len(FirstList)-1];
echo(len(FirstList),LastOne);
This piece of code first changes the content of a variable and then echoes
the last entry into the list. More sophisticated versions of this design
could be used to construct a library that allows transparently to execute
imperative code in OpenSCAD, with the compiler none the wiser.
// sum up all elements in list
AddUp=[for (i=[1:1:len(FirstList)-1]) FirstList[i-1]+FirstList[i]];
Sum=AddUp[len(AddUp)-1];
echo(AddUp,Sum);
And if you read FirstList from an external file, you have input/output
facilities for OpenSCAD.
Not convenient and rather roundabout? I agree wholeheartedly. But it is
possible . . .
Now, translate above into (pseudo)Assembler instructions. This would look
something like:
1: move mem_A Register_A // load a value into a register
2: add mem_B Register_A // do some work, here adding another number
to what is in Register_A
3: move Register_A mem_C // save the result
4: jump 1 // repeat the work
Control routines, i.e. when to skip line 4, I have omitted, as they are not
essential to my argument.
The distinction here between imperative and functional programming is that
for imperative code, line 3 is optional and the compiler does not enforce
its presence. But for true functional programming, each memory location can
accept a value only once and thus, each intermediate result needs to be
saved. This in turn says that functional programming burdens the CPU with
more work, and that means the CPU is slower. You can, of course, permit the
compiler to be more lenient and not store every intermediate result. But
that is fudging the issue . . . As it does speed up program execution!
If all three memory locations are in my level 1 cache, each Assembler
instruction will take one clock cycle and the whole lot just over one
nanosecond on my machine. But if they are not in level 1 cache, the cache
controller will require time to fetch it, from level 2 cache, if it is
there, from level 3 cache, if it is there, from general memory, if it is
there, from the hard disk cache, if it is there, and if the data are nowhere
to be found, from the swap file on my hard disk. Since that turns at
7200rpm, data read rate is 7200/60=120bit/second/read head. This means there
is speed differential between data from the fastest memory location (=cache)
to the slowest of about 1 in 10 million! And again, details like latency I
have not considered, as they only lower speed even further. What I have
observed is that speeding up by a factor of 70000 (2 hours /0.1 seconds) is
possible, not all of it originating from imperative vs functional coding
style. So far, I can assign only a factor of 100 to it, from 11 seconds to
0.1 seconds.
Since you have asked for it, libraries I do not use at all, if I can
possibly avoid it. Coding speed is not an issue for me, understanding what I
am coding, and why, is. And therefore, I take issue with people who provide
misleading answers, people who waste my time, and that of others. Code that
I write is unlikely to ever leave the level of experimental code. That is
good enough for me. But what I learn from writing this code I share with
those who care to listen, and only them.
wolf
--
View this message in context: http://forum.openscad.org/The-variable-does-not-retain-the-changed-value-tp18219p18278.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Where is the reassignment to a variable in your example? You just made a
second list that is the sum of pairs of the first list. No list contents
were modified.
Just because a functional language doesn't allow reassignment it doesn't
mean that the compiler can't reuse memory. In fact compilers for imperative
languages often create an intermediate code that produces a new symbol for
each assignment and then allocates and re-uses registers and memory the
most efficient way it can. The result bears little relationship to the
source code.
On 31 August 2016 at 11:37, wolf wv99999@gmail.com wrote:
When OpenSCAD got equipped with List Comprehension, the compiler-enforced
prohibition against true variables fell by the wayside. A list may be used
as the foundation of a user-controlled memory system. Consider this code:
// create list
FirstList=[for (i=[0:1:6]) i];
LastOne=FirstList[len(FirstList)-1];
echo(len(FirstList),LastOne);
This piece of code first changes the content of a variable and then echoes
the last entry into the list. More sophisticated versions of this design
could be used to construct a library that allows transparently to execute
imperative code in OpenSCAD, with the compiler none the wiser.
// sum up all elements in list
AddUp=[for (i=[1:1:len(FirstList)-1]) FirstList[i-1]+FirstList[i]];
Sum=AddUp[len(AddUp)-1];
echo(AddUp,Sum);
And if you read FirstList from an external file, you have input/output
facilities for OpenSCAD.
Not convenient and rather roundabout? I agree wholeheartedly. But it is
possible . . .
Now, translate above into (pseudo)Assembler instructions. This would look
something like:
1: move mem_A Register_A // load a value into a register
2: add mem_B Register_A // do some work, here adding another number
to what is in Register_A
3: move Register_A mem_C // save the result
4: jump 1 // repeat the work
Control routines, i.e. when to skip line 4, I have omitted, as they are not
essential to my argument.
The distinction here between imperative and functional programming is that
for imperative code, line 3 is optional and the compiler does not enforce
its presence. But for true functional programming, each memory location can
accept a value only once and thus, each intermediate result needs to be
saved. This in turn says that functional programming burdens the CPU with
more work, and that means the CPU is slower. You can, of course, permit the
compiler to be more lenient and not store every intermediate result. But
that is fudging the issue . . . As it does speed up program execution!
If all three memory locations are in my level 1 cache, each Assembler
instruction will take one clock cycle and the whole lot just over one
nanosecond on my machine. But if they are not in level 1 cache, the cache
controller will require time to fetch it, from level 2 cache, if it is
there, from level 3 cache, if it is there, from general memory, if it is
there, from the hard disk cache, if it is there, and if the data are
nowhere
to be found, from the swap file on my hard disk. Since that turns at
7200rpm, data read rate is 7200/60=120bit/second/read head. This means
there
is speed differential between data from the fastest memory location
(=cache)
to the slowest of about 1 in 10 million! And again, details like latency I
have not considered, as they only lower speed even further. What I have
observed is that speeding up by a factor of 70000 (2 hours /0.1 seconds) is
possible, not all of it originating from imperative vs functional coding
style. So far, I can assign only a factor of 100 to it, from 11 seconds to
0.1 seconds.
Since you have asked for it, libraries I do not use at all, if I can
possibly avoid it. Coding speed is not an issue for me, understanding what
I
am coding, and why, is. And therefore, I take issue with people who provide
misleading answers, people who waste my time, and that of others. Code that
I write is unlikely to ever leave the level of experimental code. That is
good enough for me. But what I learn from writing this code I share with
those who care to listen, and only them.
wolf
--
View this message in context: http://forum.openscad.org/The-
variable-does-not-retain-the-changed-value-tp18219p18278.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