discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

The variable does not retain the changed value.

W
wolf
Wed, Aug 31, 2016 10:37 AM

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.

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.
NH
nop head
Wed, Aug 31, 2016 11:18 AM

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

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 >