Torleif: If I add 'c="TOP";' to the beginning of the program, then I get
ECHO: "TOP"
ECHO: "TOP"
which is correct behaviour for lexical scoping.
If I then wrap this entire program in a module, like so:
module top()
{
...
}
top();
then the behaviour doesn't change, so that's lexical scoping inside a
module.
On 1 February 2018 at 23:45, TLC123 torleif.ceder@gmail.com wrote:
Sent from the OpenSCAD mailing list archive http://forum.openscad.org/
at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Oh wow...
Thanks for the tip!
On 2/1/18, doug moen doug@moens.org wrote:
Thanks, Simeon. You might also want to look at Matt Keeter's libfive. It's
another implicit-function 3D modelling language, based on the Guile dialect
of Scheme. https://github.com/libfive/libfive
On 1 February 2018 at 22:21, Simeon Veldstra sim@puddle.ca wrote:
Oh, I see, "broken scoping" might be a clearer term perhaps.
The docs pretty clearly discourage reassignment at least, and the
language gives us let.
I was happy to discover OpenSCAD. Despite its warts, it suits my
style of thinking. ImplicitCAD and Ruckus were exciting to
find, but appear to be dead projects. I'm enjoying digging into
Curv, keep up the good work!
I'm quite sure you know more about language design than I do. I
find it a fascinating subject and thought my comments would be of
interest to the list.
On 2/1/18, doug moen doug@moens.org wrote:
Yes, but what I call "dynamic scoping" in OpenSCAD is not the same as
dynamic scoping in Lisp. So I don't think that references to the theory
of
Lisp interpreters helps much.
Example 1.
1 a = 0;
2 module m()
3 {
4 function f() = a;
5 x = f();
6 a = 1;
7 y = f();
8 echo(x,y);
9 }
10 m();
Look at line 4. In a lexically scoped language, the variable name 'a'
would
statically refer to either the outer definition on line 1, or the inner
definition on line 6. One or the other. But in OpenSCAD the scope of
'a'
seems to be chosen at runtime, and varies dynamically. So the output
is:
ECHO: 0,1
Example 2.
1 a = 0;
2 function f() = a;
3 module m()
4 {
5 x = f();
6 a = 1;
7 y = f();
8 echo(x,y);
9 }
10 m();
Here, the output is "ECHO: 0,0". In this case, the variable 'a' is
lexically scoped within the function 'f'. In the previous case, the
variable 'a' was dynamically scoped within the function 'f'.
To me, this looks like a bug. It's as if the intention was to implement
lexical scoping, but the implementation is buggy. Marius has previously
stated that we can't fix this bug in a way that changes the behaviour
of
existing programs.
On 1 February 2018 at 11:37, Simeon Veldstra sim@puddle.ca wrote:
On 1/31/18, doug moen doug@moens.org wrote:
...
One caveat. In the style of language interpreter I'm familiar with,
variable and argument references are lexically scoped. In Curv, I
compile
variable and argument references into slot indexes, which index into
the
slot array of the current stack frame. So the scope of a variable
name
is
fixed at compile time, before the program is evaluated. This is
probably
why the Curv interpreter is so much faster than the OpenSCAD
interpreter:
array indexing is faster than hash table lookup. By contrast,
OpenSCAD
is
dynamically scoped. Variable and argument references are names, and
these
names are looked up dynamically during evaluation, which leads to
semantics
that are different from lexical scoping. The same variable name node
in
the
parse tree may have different scopes in different calls to the same
function or module. So you'll have to figure out how to preserve
these
dynamic scoping semantics if you implement this style of compiler,
and
I'm
not sure there are any references to help you, because the dynamic
scoping
semantics of OpenSCAD seem utterly unique to me.
Emacs lisp is another place where dynamic scope is found. This is
considered a mistake by some, and lexical scoping has been added
to recent versions.
https://www.emacswiki.org/emacs/DynamicBindingVsLexicalBinding
I suppose you could index into a global table of slots to
implement dynamic scope in the compiler you describe, but it
would not be an improvement, except perhaps if your goal was
compatibility. Dynamically scoped programs are considerably
harder to reason about than lexically scoped programs. This is
true both for humans and optimizing compilers.
You can get dynamic scope by accident in an interpreter with a
slight change in how you handle the environment.
The best explanation I've seen for this is published here:
http://cs.brown.edu/courses/cs173/2012/book/From_
Substitution_to_Environments.html
In Shriram Krishnamurthi's excellent book
Programming Languages: Application and Interpretation
--
sim
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
--
sim
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
--
sim
What is the application of a 2-3 tree in geometry, specifically in OpenSCAD?
$ Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 ); $ tips: Collection of tips on github
--
Sent from: http://forum.openscad.org/
runsun wrote
What is the application of a 2-3 tree in geometry, specifically in
OpenSCAD?
I did it as an exercise. I expected there to be a need for a data
structure with search,insert and remove, but I guess people just munge lists
instead.
--
Sent from: http://forum.openscad.org/
NateTG wrote
I did it as an exercise. I expected there to be a need for a data
structure with search,insert and remove, but I guess people just munge
lists
instead.
Thx Nate. I might find it useful later when doing some geometrical calc.
$ Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 ); $ tips: Collection of tips on github
--
Sent from: http://forum.openscad.org/
A 2-3 tree is an efficient balanced tree and it might be helpful to store
geometrical data that should be sorted for fast retrieval. To be useful, a
2-3 tree data structure should store a register containing the relevant
geometrical data besides the sorting key. A simple example of that is the
quicksort method that is found in the OpenSCAD manual [1]. It allows to
sort an array of numbers. However, it is useless to sort a list of points
by its first coordinates a much more useful task. I had to write my own
version.
[1]
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/List_Comprehensions#Sorting_a_vector
2018-02-12 20:53 GMT-02:00 runsun runsun@gmail.com:
NateTG wrote
I did it as an exercise. I expected there to be a need for a data
structure with search,insert and remove, but I guess people just munge
lists
instead.
Thx Nate. I might find it useful later when doing some geometrical calc.
Yeah, it would be nice if there were a way to make the tree generic so that
it works with many different comparison functions.
--
Sent from: http://forum.openscad.org/
Yeah, it would be nice if there were a way to make the tree generic so that
it works with many different comparison functions.
Since we don't have first class functions in OpenSCAD, a simple alternative
solution would be to insert arrays in the tree: by convention the sorting
key is the first element of the array and the remaining is something to be
interpreted by the calling code. Like, for instance:
function quick_sort(arr, simple=true) =
!(len(arr)>0) ? [] :
let( pivot = simple ? arr[floor(len(arr)/2)] :
arr[floor(len(arr)/2)][0],
lesser = [ for (y = arr) if ( (simple ? y : y[0]) < pivot ) y ],
equal = [ for (y = arr) if ( (simple ? y : y[0]) == pivot ) y ],
greater = [ for (y = arr) if ( (simple ? y : y[0]) > pivot ) y ]
)
concat( quick_sort(lesser, simple),
equal,
quick_sort(greater, simple) );
l = [ 5,2,8,0,4,7 ]; // simple list of numbers
echo(quick_sort(l));
// ECHO: [0, 2, 4, 5, 7, 8]
v = [ [-1,2], [-7,[4]], [-9,2,4,5], [-3] ]; // list of non void lists
echo(quick_sort(v, simple=false));
// ECHO: [[-9, 2, 4, 5], [-7, [4]], [-3], [-1, 2]]
@Ronaldo, nice code. It's very fast -- sorting 100,000 pts 10 times cost only
6 sec. Pulling the 'simple?' check out of the loops, like this:
gained a little speed (100,000 x 10 => 5 sec) but i guess even in extreme
use of OpenSCAD it doesn't matter.
$ Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 ); $ tips: Collection of tips on github
--
Sent from: http://forum.openscad.org/
Inspired by Ronaldo's code, here is a more generalized quick sort for arrays:
<br/>
/*
ECHO: [[2.9, 1.9, -2.8], [-2.5, -1.5, -2.9], [-0.1, 2.8, 2.4], [0.9, 1.8,
0.8], [-1, -1.3, -0.8]]
[[-2.5, -1.5, -2.9]
, [-1, -1.3, -0.8]
, [-0.1, 2.8, 2.4]
, [0.9, 1.8, 0.8]
, [2.9, 1.9, -2.8]]
[[-2.5, -1.5, -2.9]
, [-1, -1.3, -0.8]
, [0.9, 1.8, 0.8]
, [2.9, 1.9, -2.8]
, [-0.1, 2.8, 2.4]
]
[[-2.5, -1.5, -2.9]
, [2.9, 1.9, -2.8]
, [-1, -1.3, -0.8]
, [0.9, 1.8, 0.8]
, [-0.1, 2.8, 2.4]]
*/
$ Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 ); $ tips: Collection of tips on github
--
Sent from: http://forum.openscad.org/