Hi Parkinbot. Just a note about constant vs variable declarations.
In Algol 68:
real pi = 3.1416; // constant declaration
real x := 0; // variable declaration, initialized to 0
x := x + 1; // assignment statement
In Pascal:
const pi = 3.1416; // constant declaration
var x := 0; // variable declaration
x := x + 1; // assignment statement
In Javascript:
const pi = 3.1416;
var x = 0;
x = x + 1;
In OpenSCAD (with mutable variables)
pi = 3.1416; // constant declaration
var x := 0; // variable declaration
x := x + 1; // assignment statement
There is no imperative language that uses the same syntax for both a
constant declaration and for an assignment statement. It's too late to
change OpenSCAD to use a different syntax for constant declarations. So I
can't use '=' for the assignment statement.
You said: "It is a bit misleading and hard to
understand for novices (or mainly imperative programmers, like me) that
immutable variables are allowed as L-values after first use in OpenSCAD and
that the last assignment will kind-of supersede all other assignments"
That's a design flaw in the language, which I propose to fix.
It's a side effect of an important feature. You can include a script that
contains a top level constant declaration X, then you override the value of
X in the parent script.
include <lib.scad> // defines X
X = 1; // override X
The problem is that the include statement just mashes the included file
into the same input stream as the parent, and OpenSCAD doesn't tag constant
declarations with the original source file in which they are defined
(yet--Marius has a branch that will fix this).
So we have no way to issue an error message for
X = 0;
X = 1;
because the first X=0 could have originated in an include file, and the
second X=1 could be an override in the parent, we just don't know.
Once Marius merges his branch, then it will be possible to issue a warning
or error message for a duplicate constant declaration, both in the same
source file, and we can stop pretending that this is legal code.
On 31 May 2016 at 08:10, Parkinbot rudolf@parkinbot.com wrote:
Doug,
yeah the design now looks a lot simpler and straight forward. I'd be able
to
live with it, so please take my annotations as suggestions to keep the
discussion going on.
There is by far no Frankenstein monster coming up. Hey, even Mac OS can be
run on PC-hardware meanwhile and the world is still revolving. Escaping the
'const' restrictions and random write access is unavoidable for a modern
language, as to many inelegant and time consuming work arounds have to be
used to accomplish even simple tasks like summing up or matrix
manipulation.
Also I wouldn't sweep Neon's argument from the carpet to use a full grown
language in declarative embedding. I'm just afraid, this will take away
most
of the fun the dev team is having to create an own thing. If I had time,
I'd
try to blow up Matlab with a toolbox written in native C++ that can act as
a
fast OpenGL viewer at CSG level. I guess such a component is already
available and its just a question of interfacing. By building on an already
mighty language you can concentrate on the important things. Blender ist a
good example for this approach. Also similar approaches, not being so much
overloaded, are currently popping up.
Personally I'm still not very happy with the keyword 'do' which is being
used for procedural things (mainly oops) in other languages. But, it has an
imperative connotation. So why not.
Also having '=' and ':=' in the same language for assignments, WILL be
confusing, anyway you look at it. I started programming with ALGOL68, where
':=' was used solely for variable declaration with init, while later
reassignments where done with '='. This is, what your 'var' keyword does.
Later I was programming in Pascal/Delphi/C++/VB in a kind of mixed fashion
and I really got crazy about this, especially when trying to reuse code
that
crossed borders.
But in those (imperative) languages immutable (=const) variables just are
not allowed to be noted as L-values. It is a bit misleading and hard to
understand for novices (or mainly imperative programmers, like me) that
immutable variables are allowed as L-values after first use in OpenSCAD and
that the last assignment will kind-of supersede all other assignments,
while
some scoping rules (that only seem to be perfectly known only by the
interpreter :-) ) are enforced for expressions like A = A+1. As far as I
remember, those rules have changed over time, and it was not allowed in
earlier versions, but it has somehow drippled in und I guess has to be kept
for compatibility reasons.
Maybe I am wrong with all this, because I never started to seriously use
this language for productive things nor did any documentation on it.
Usually
I struggle my way through, writing also a lot superfluous test code and
stuff, to find out interrogatively which opinion a compiler or interpreter
has on certain expressions - at least in lack of a debugger. But this just
as background, because most multi-language users (who is not in our days?)
will be in the same 'Babylonian' situation.
I'd still say
function myfunc = do{
var x := 1;
...
is triple marking. But better than nothing :-) Omitting things in later
versions is better than having forgot crucial things in earlier versions.
--
View this message in context:
http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17483.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
On 31. mai 2016 16:09, doug moen wrote:
Hi Parkinbot. Just a note about constant vs variable declarations.
In Algol 68:
real pi = 3.1416; // constant declaration
real x := 0; // variable declaration, initialized to 0
x := x + 1; // assignment statement
In Pascal:
const pi = 3.1416; // constant declaration
var x := 0; // variable declaration
x := x + 1; // assignment statement
In Javascript:
const pi = 3.1416;
var x = 0;
x = x + 1;
In OpenSCAD (with mutable variables)
pi = 3.1416; // constant declaration
var x := 0; // variable declaration
x := x + 1; // assignment statement
There is no imperative language that uses the same syntax for both a
constant declaration and for an assignment statement.
Try this:
In C++
const double pi = 3.1416; // constant declaration
double x = 0; // variable declaration, initialized to 0
x = x + 1; // assignment statement
In Angelscript:
const double pi = 3.1416; // constant declaration
double x = 0; // variable declaration, initialized to 0
x = x + 1; // assignment statement
Carsten Arnholm
Oh my god, half of my Algol68 is gone ;-) I admit I could have looked it up.
I just remember there were monster terms like 'REF REAL x = LOC REAL := pi'
from which most parts could be omitted. But anyway, the main problem was the
struggle with the punch cards ...
The difference is all about modifiers and not about the operator, which can
easily be overloaded for each modifier (as it is for the different data
types). But never mind, ':=' is not such a bad deal and you are on the safer
side. Lazy people like me prefer to write Tx(10) instead of translate([10,
0, 0]) and to use short variable names like 'x' plus maybe a comment on
first use, instead of 'My_Main_Diameter_For_Circular_Integration' but this
is really a matter of taste.
It's a side effect of an important feature. You can include a script that
contains a top level constant declaration X, then you override the value
of X in the parent script.
include
<lib.scad>
// defines X
X = 1; // override X
which will (another flaw?) not hold for
use
<lib.scad>
So putting
$fn=4;
globally into a lib, can be nasty, especially if the included lib does the
'use'. But this leads into the qualifier discussion, which should not be
neglected.
--
View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17486.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
On 1 June 2016 at 02:46, Carsten Arnholm arnholm@arnholm.org wrote:
In C++
const double pi = 3.1416; // constant declaration
double x = 0; // variable declaration, initialized to 0
x = x + 1; // assignment statement
In Angelscript:
const double pi = 3.1416; // constant declaration
double x = 0; // variable declaration, initialized to 0
Those are not the same syntax -- the constant declarations have "const" in
front (and the same for the Javascript example), and the assignment doesn't
:-)
On 31. mai 2016 22:41, Len Trigg wrote:
On 1 June 2016 at 02:46, Carsten Arnholm wrote:
In C++
const double pi = 3.1416; // constant declaration
double x = 0; // variable declaration, initialized to 0
x = x + 1; // assignment statement
In Angelscript:
const double pi = 3.1416; // constant declaration
double x = 0; // variable declaration, initialized to 0
x = x + 1; // assignment statement
Those are not the same syntax -- the constant declarations have "const"
in front (and the same for the Javascript example), and the assignment
doesn't :-)
Without const they would not be constant declarations. If you want a
variable declaration, then drop the const. The constant declaration
syntax using '=' is the same as for variable declarations and
assignments, unlike the other examples.
My point is that simple concepts should ideally be expressed directly
and consistently, not in subtle and indirect ways that few will
understand and accept.
Carsten Arnholm
With "https://github.com/openscad/openscad/wiki/Mutable-Variables" doug.moen
has written a specification for imperative extensions to the
OpenSCADlanguage that in version 2.0 is full of design bugs. So are the
comments written so far.
Before I deal with them, remember that the lowest level of computer language
is assembler. Within assembler, you are permitted to MOV (write, in English)
a value from one location to another (e.g. from a register onto the stack).
If that MOV went to the location it was supposed to go, great. But if it
went somewhere else, you have a BUG! If you use a compiler as intermediate
between your program and assembler, you have a good chance of catching it
before the bug does irreparable damage, and your program fails. In catching
a bug, a functional language has an advantage over an imperative language,
since the compiler knows (almost) everything about the programmer's
intentions.
A Haskel fan has this to write
(http://www.haskellforall.com/2012/01/haskell-for-c-programmers-for-loops.html)
"Haskell is an excellent language because functional programming is the
perfect foundation for rigorously building more sophisticated abstractions.
Imperative languages can't do this because they can't opt-out of state and
side effects, making it incredibly difficult to reason about the correctness
of abstractions."
"state and side effects" is just a way of fudging the real issue: if you
don't read or write the proper memory location, your program state is likely
to be busted, and you have side effects.
The Rust programming language (https://doc.rust-lang.org/book/unsafe.html)
is more clear about the issues at stake here. It clearly distinguishes
between writing safe and unsafe code:
"Safe, in the context of Rust, means ‘doesn’t do anything unsafe’. It’s also
important to know that there are certain behaviors that are probably not
desirable in your code, but are expressly not unsafe. . . Rust cannot
prevent all kinds of software problems. Buggy code can and will be written
in Rust."
The paper then goes on to describe what the compiler cannot be expected to
catch, safe mode or unsafe mode.
Doug.moen has written his "Mutable-Variables" paper from the viewpoint of a
user. Had he used the viewpoint of a compiler, he would have realized the
bugs he has introduced.
Here they are:
c=3.1416; // this defines an immutable variable (a constant). The
compiler does not need more information, it can
define
the data type itself
var x;
var x:=0; // the compiler needs more information, it does not know is
this a double or single precision number, an
integer, or a
character? There is a need for what in C is called a
header.
x=x+1; // the use of a colon is not necessary and has been omitted
here. Since x is already defined as mutable
elsewhere, the
compiler has all the necessary information. x=x+1
is perfectly
acceptable.
c=c+1; // This is illegal code, as c is auto-typed by the compiler
as immutable. The compiler should flag it as
"Variable not
assigned". If done so, no unexperienced user is
likely to lug
his/her lack of understanding onto this forum.
With regards to the use of procedures (if, as I assume, he means Pascal-type
procedures), I fail to see their utility. A procedure does exactly the same
as a function, except that it does not return a value. Rather, I would like
to see a clean-up of how a function is currently written so that it is
possible to build a function from compound statements. This would also make
functions much more easily readable. Readability is more of an issue here
than capability, in particular if you want to scope a mutable variable to be
limited to that function. And from what I can gather from the paper, a "do
block" would be just another name for a procedure: another function that
writes some memory area, but does not return anything and would not expand
on OpenSCAD's ability to create shapes.
What "assert()" is supposed to do I cannot make out at all.
If, while and for are great to have, provided C-style programming is
avoided. What I want to have is an OpenSCAD that is easy to learn, without
first becoming an expert in C. Therefore, no C-style anywhere. C-style is
good for C programmers only, for all others it is a pain in the backside and
barely readable. If you can read English, you should be able to read
OpenSCAD. If not, improve the language and make it more like English. Be
verbose where you must; if you really want to be universal, program in
assembler. And if you want to be truly concise, maybe you should use
Haskell?
I am very much in favour of using "mutable variables". But there are limits,
as I pointed out elsewhere
(http://forum.openscad.org/feedback-on-quot-C-style-for-quot-td17512.html).
Rust has defined these limits in terms of "safe" vs "unsafe" code. I suggest
that the OpenSCAD developer community do something similar for OpenSCAD, if
they fear imperative programming taking over their beloved functional style
nonsense and poor readability (in places).
Keep OpenSCAD simple, focused upon the creation of shapes, and implement
OpenSCAD2 as soon as possible. For those who want extensions to the
language, allow them to write a library (and its associated manual) and add
it to OpenSCAD for a limited number of years, the same way MCAD got added.
Throw the library out if it, or its manual, is not maintained or does not
get used.
That is enough criticism (hopefully constructive). The other bugs in the
discussion so far you should be able to discern yourself, once to see the
issues from a compiler's perspective.
wolf
--
View this message in context: http://forum.openscad.org/Polygon-using-relative-points-rather-than-absolute-tp17414p17522.html
Sent from the OpenSCAD mailing list archive at Nabble.com.