doug-moen / openscad2

better abstraction mechanisms for OpenSCAD
Boost Software License 1.0
25 stars 3 forks source link

First Class Values #4

Closed gwadej closed 9 years ago

gwadej commented 9 years ago

I have been digging through this for a while before realizing that you pulled a fast one. You are no longer using the term variables and are calling them values instead. Is this intentional. If it's not, it should be.

To be pedantic, I would also suggest referring to 1, 20, and 'foo' as literals, to distinguish them from named values.

doug-moen commented 9 years ago

I want to make sure my use of terminology is consistent and correct, and doesn't cause confusion. So I'm going to think this through carefully. This is part 1 of a two-part post.

The word 'variable' has a perfect good meaning in mathematics and logic. It is a name that stands in for a value. In algebra, you can write the equation

x + 2 = 12

and solve for x, to discover that x is 10. In particular, note that

x = x + 1

is a perfectly legal algebraic equation, but it defines a number x that is equal to its successor. There is no such number, so the equation has no solution. Also note that '1' is not a variable. It is an integer, it is a constant, but it is not a variable.

In the lambda calculus, the parameter of a lambda expression (function) is a variable. In high school algebra, you have function definitions like this:

f(x) = x + 1

and x is a variable that is bound to a different value each time the function is applied to an argument.

In programming languages, unfortunately, the word "variable" is co-opted to mean different things in different languages, and this is a source of confusion.

In Fortran and Algol (invented in the 1950's), and the imperative languages that followed them, a "variable" is an identifier that is bound to a storage location. If a variable is referenced in an expression, then we fetch the current value from the storage location. If a variable is referenced on the left side of an assignment statement, then we store a new value in the storage location. In Fortran et al,

x = x + 1

is an assignment statement that increments the value in x's storage location, it is not an equation specifying the value of x.

In Haskell, there are variables, but they are of the mathematical kind. For example,

let x = x + 1

is a perfectly valid definition of 'x' in Haskell. When you reference 'x', Haskell tries to solve the equation, and fails (it goes into an infinite loop). Haskell is a strongly typed language with polymorphic functions, and so it also has type variables which occur in function types. These, too, are the mathematical kind of variable.

Modern, strongly typed imperative languages have the Fortran kind of variable, but they also have Haskell-like type variables in their function types, which are of the mathematical kind. This leads to terminological confusion about what the word "variable" means within a single programming language.

Since OpenSCAD is a functional language, it would be reasonable to use the word "variable" in the mathematical sense, as with Haskell. I've just searched through the OpenSCAD documentation, and I think most uses of the word "variable" are consistent with this.

But there is still some confusion, caused by the fact that OpenSCAD has C-like syntax, and it has "assignment statements", and you can "assign" a variable more than once, which makes it look suspiciously like an imperative language.

For example,

Variables in OpenSCAD are simply an identifier followed by an assignment via an expression (i.e. identifier = expression).

Variables are set at compile-time, not run-time Because OpenSCAD calculates its variable values at compile-time, not run-time, the last variable assignment will apply everywhere the variable is used (with some exceptions, mentioned below). It may be helpful to think of them as override-able constants rather than as variables.

And the following sentence is just wrong:

Note that the len() function is not defined when a simple variable is passed as the parameter.

This refers to the fact that len(42) returns undef. This sentence refers to 42 as a "simple variable". It is not a variable. The text should say "simple value".

The word "value" is generally used correctly, with the same meaning as in mathematics or functional programming. I only found one mistake:

You can instantiate the module by passing values (or formulas) for the parameters just like a C function call:

This text refers to a literal constant like 0 as a "value", to distinguish it from an expression like x+1 which is a "formula".

doug-moen commented 9 years ago

Part 2. What terminology should I use in the OpenSCAD2 spec? Should I use the word "variable"?

I'm pretty sure I don't want to use the term "assignment statement", because this term comes from Fortran, and is used almost exclusively in the imperative language sense. I use the word "definition" to describe the following syntax:

x = 0;
f = function(i) i + 1;
g(i) = i + 1;

The meaning of a definition is that the identifier on the left and the expression on the right can be freely substituted for each other without changing the meaning of the program. That's not the meaning that people associate with the term "assignment statement".

So in the above definitions, should I refer to x, f and g as variables? Some people might find this odd. It would be reasonable to describe x as a constant and f as a function, and it is common to use the word "variable" to describe something that's not a constant or function.

In the latest version of Lexical Scoping, I say that a definition binds an identifier to a value. And this results in a binding, which is an association of an identifier with a value. That is correct use of terminology.

The word "binding" is good enough, in the small number of places where I need a general term for what a definition creates. I agree that the term "named value" is a problem, and I'll get rid of it. "Named value" only appears in two places, and it's my own invention, not a standard industry term.

I'll eliminate or rewrite the text that says OpenSCAD2 doesn't have variables, based on the discussion in part 1 of this post.

gwadej commented 9 years ago

My main point about the term variable has been the confusion for new users. It seems like every few months the list goes over the "OpenSCAD variables are broken because they don't act like {insert favored programming language here}" debate. Asserting that the definition is valid in the mathematical or functional programming sense doesn't help with most programmers coming to use the language. (As we've seen time and time again.)

Most of us do learn eventually to see OpenSCAD variables as different than C/C++/Java/Ruby/Python/Whatever variables. Especially those with more than one language under their belt. But, it is a source of ongoing confusion.

In the last couple of standards, C++ has made a distinction between an assignment and an initialization. We could probably use a different term like initialization, definition, or something for setting up a variable and that might reduce some of the confusion.

Picking the right notation (or in this case terminology) could reduce some confusion.

I do like the way you are thinking this through, but I think we need to make allowances for the audience that the doc will serve.

doug-moen commented 9 years ago

In the current text, the only use of the word "variable" is the claim that OpenSCAD1 has three namespaces (for variables, functions and modules) while OpenSCAD2 has a single namespace. Variations of that text occur several times.

The only use of "assignment" is a paragraph that explains why OpenSCAD2 doesn't use the term "assignment statement", and uses "definition" instead.

I don't want to use the term "initialization", because that only makes sense in an imperative programming languages, where a Fortran-style variable is a name bound to a storage location, and the storage must be properly initialized before it is used. I think my current language, stating that a definition binds an identifier to a value, is good and accurate.

There will have to be an OpenSCAD2 user manual, which will need to be significantly different from the current documentation in some places. It will have to address the issues that you have raised. Elsewhere, you talked about the need to document idioms, and that's a great idea. I'm not writing a user manual right now, just describing the differences between OpenSCAD1 and OpenSCAD2, and explaining the rationale.

If you have a specific suggestion for how the current text could be improved, or you can point to something specific you think is unclear, let me know.

gwadej commented 9 years ago

I don't particularly care for initialization, either. But, I do think that replacing the term "assignment" for the concept of "defining a variable", or "binding a value to a name", or "naming a value", would help with the confusion that people are experiencing.

While not a user doc, the concepts you are defining here will influence the way the user doc is written. We can probably avoid user-specific terminology for a while, but eventually we'll need to address the impedance mismatch between the spec and the way the user sees the language.

That being said, your new text is much clearer and more precise than what we've had in the past. I'm more looking to help with the back of the brain processing that may be useful later in the process.