4

A principle that I follow is that, when an identifier is established, it should be a signal to the reader that the value referred to is indeed an abstraction which will be used more than once. That is, the identifier is defined or assigned once, and the value is read more than once.

However, a common idiom exists whereby, in order to increase readability, parts of a complex expression are factored out into variables. These variables will only be used once, violating the principle.

Thus, a special separate class of identifier should be used to indicate a one-use variable.

This principle applies to any identifier. So you might have one-use functions, one-use methods, one-use variables, etc.

Has there ever been a programming language which supported one-use variables?

8
  • 1
    Most languages have them, and they're called "constants".
    – Marc B
    Jan 12, 2012 at 4:14
  • 4
    @MarcB Constant variables can be referred to more than once.
    – dharmatech
    Jan 12, 2012 at 4:15
  • 1
    Have you looked into functional languages like Erlang and Haskell? There variables are immutable and all "variables" are basically functions. If so, how does that differ from what you're asking about?
    – deceze
    Jan 12, 2012 at 4:15
  • 2
    @MarcB: Your comment doesn't address the following point made by the OP: "...a common idiom exists whereby, in order to increase readability, parts of a complex expression are factored out into variables...". Jan 12, 2012 at 4:21
  • 1
    constants hang around and use up memory and pollute the namespace so they do not feel appropiate as one-use variables which would release the memory and clean the name Jan 13, 2012 at 4:14

8 Answers 8

19

In type theory, single-use variables are modeled with (a derivative of) linear logic. In linear logic, a proposition can only be used once; linear logic is sometimes seen as a logic of resources. In linear logic, if you want to use A twice, you need to have A⊗A (both A and A) available; if you want to use A as many times as you like, you need to have !A (“of course A”).

Linear logic has not made it into many mainstream programming languages. It is the foundation of uniqueness typing in the clean programming language which is used to model side effects. In Clean, an expression of type Int denotes a pure computation that produces an integer value, i.e. a computation that can be made at any time, or multiple times, without changing the behavior of the program. An expression of type u:Int denotes a computation that produces an integer and that must be performed exactly once, for example because it performs a side effect.

0
4

You should probably take a look at ATS and Mercury. Both have support for linear types, although in different paradigms.

In particular I would to add, that ATS uses linear types for tracking resource usage, and this has both performance and correctness implications, e.g. allowing explicit memory reclamation and supporting efficient mutable arrays.

Also, terms of linear types are not necessarily "used once", but I will not go that far (PDF).

3

You can use auto storage class variables in C this way. Just start a new block with {, declare and initialize some auto variables, do your calculation, then close the block with }, and all the auto variables in the block go away. An example from some code of mine:

{
    int term = tar->array[i];
    int offset = isnegation(term) ? 41 : 0;
    int var = variable(term);
    int bx = ((var + offset) / bits_per_sigblock) % CLAUSE_SIGNATURE_SIZE;
    int shift = ((var + offset) % bits_per_sigblock) - 1;
    sp[bx] |= (signature_type)1 << shift;
}

This could have been rolled into one line of code, but it would have been unreadable, even to me!

2
  • 1
    Yep, I'm a fan of C blocks to limit scope of variables which are only referred to once. :-)
    – dharmatech
    Jan 12, 2012 at 4:34
  • This is supported in several languages other than C; C#, Java and C++ at the very least all have the same construct. In every language I can think of which would be in semi-common use, you could always factor the portion into some sort of function of its own.
    – user
    Jan 13, 2012 at 9:55
2
  • Haskell has a where construct that fits your description, as well as let…in.
  • The Lisp/Scheme family have let, letrec and let*.
  • ML also sports let…in.
2
  • 1
    The bindings established by lambda (and thus let, let*, etc) can all be referred to more than once. Thus they are not one-use variables.
    – dharmatech
    Jan 12, 2012 at 4:18
  • 1
    @dharmatech: Then, AFAIK, no such construct exists. The purpose of the constructs that I listed is to restrict access to a given value to within the scope a single expression, which is the predominant factor in avoiding accidental misuse of the variable. The fact that the expression can use the variable more than once isn't very interesting. Jan 12, 2012 at 4:25
2

My buddy Joe Groff sent an answer via email:

Those are called "uniqueness types". The Clean programming language is a pure functional language that builds its side-effect management system around them. IIRC Mercury and Oz also support uniqueness types, and there's a GHC extension that allows uniqueness annotation in Haskell. C++11 has them too in the form of rvalue references.

1

Technically any such factored out variable is going to be used twice: first to store the result of some sub-expression, and then as a reference to that result as part of the larger expression.

As you've experienced most languages also support one-use variables in the sense that it's perfectly possible to use that idiom. Is there some specific different handling of them that you'd like?

SHould they be removed from the namespace after use? Or do you just want a way to indicate "don't get attached to this variable"? The former should, hopefully, be taken care by generally limited scopes: single-use anything should be restricted to well-contained areas that they won't cause any cluttering problems in. The latter possibility should be handled by variable naming conventions or comments.

Is there something else that you'd like to have happen?

5
  • Technically any such factored out variable is going to be used twice By "one-use" I mean it will be referenced only once.
    – dharmatech
    Jan 12, 2012 at 4:23
  • I got that, but wanted to point out that storing the partial result can be an intentional act for debugging, etc.
    – blahdiblah
    Jan 12, 2012 at 4:25
  • Is there some specific different handling of them that you'd like? That's a great question and you bring up interesting options. You mention having them removed from the namespace. Another would be to keep it in the namespace but have further references trigger compile time errors.
    – dharmatech
    Jan 12, 2012 at 4:26
  • Regarding some specific handling: I think OP wants such variables to not be shared (or, which is the same, aliased) or discarded voluntarily.
    – Artyom Shalkhakov
    Jan 13, 2012 at 3:28
  • I would like to see a statement which would declare and assign a temp variable with a given name such that the value could not be reassigned, but the scope would end at the next such declaration with the same name in the same block or the start of a nested block which contains a declaration of the same name. Such declarations would effectively ensure that any use legitimate of the variable would see the value written by whatever declare-and-assign statement precedes it within the source code.
    – supercat
    Feb 3, 2014 at 23:26
0

The way concatenative or stack based languages generally use values is actually "read once", the difference being of course that there are no variables, just values on a stack.

As you're relaying on the stack most of the time (variables are usually avoided), and values are consumed by the functions ("words") reading them, you have to explicitly duplicate values that you need to refer to more than once.

In the end this accounts to a switch from what's normal and what's the exception in most other languages.

-1

In c/c++ it's one of the main uses for the trinery operator

const int color = in_the_matrix() ? red : blue;

Especially useful for things like threading/OMP where you need to show that a variable can't be modified by another thread.

2
  • 5
    How does this relate to the question? Did you perhaps intend to demonstrate single assignment and not single use? Jan 12, 2012 at 16:14
  • combined with scope blocks it's the nearest you can get in c/c++ Jan 12, 2012 at 16:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.