Why do we need constants in Rust if we have immutable variables? - variables

So I'm exploring Rust, and I have read about technical differences between constants and immutable variables. But it seems like immutable variables can do all things that constants can. Then what is the point of existence of constants, if immutable variables can fully substitute them?

There are two computational times that you should take into account:
compilation time
run time
The constant is computed at compilation time (and can be used in other compile-time computation) and hence the run time is faster, as it does need to compute it again.
Immutable variables are always computed at run time (from an external input not available at compilation time usually), and constants cannot be used there.

Then what is the point of existence of constants, if immutable
variables can fully substitute them?
While there are certainly use cases in which constants may be interchangeable with immutable variables, the main distinction between the categories of values is their semantics.
Declaring a constant immediately says a lot about what the value is to the reader: in particular, that the information that comprises the value must all be available at compile-time. This is a property which is enforced by the compiler. This sets up expectations for the reader about what the value is and what can be done with it.
Of course, the initialization of immutable variables is much more flexible. There is no mandate that these values are known at compile time, and the calculations that produce such values may be arbitrarily complex and even evolve over time.
The differences are, perhaps, mainly stylistic (in many but not all use cases) but where readability and maintainability are involved the distinction is valuable.

Related

why are languages generally either statically typed or dynamically typed (not both)?

I don't understand this. I understand the pros and cons of each, but why don't languages like Python allow you to specify the variable type yourself at initialization and function argument types and return types when you wish so the interpreter won't waste time checking it at runtime, for programs or just parts of your code where speed is important, and not do it yourself when it isn't?
It just seems waste of time for users to switch between languages kind of needlessly in these situation and for developers of the language to lose some users or not have them use their language for all of their projects because of this.
Initializing a variable (with a specific type) in a dynamically typed language would be pointless because the variable could be reassigned with a different type later on. And the type of the variable is determined by the variable to which it is assigned anyway. So making statically typing variables optional wouldn't actually provide any extra functionality.
Second, compile-time checking of function arguments wouldn't work either because the type of the variables passed to it couldn't be determined until runtime. And functions can be coded to check the types of their own arguments in a dynamically typed language, so there's no need to implement another system for this.

Is there a difference memory-wise between using Common Blocks and Modules in Fortran 90

I am recently learning Fortran without any guidance, and experimenting with different versions. I have found from this site:
Is a MODULE better than a COMMON block?
Almost always yes. The only reasons to use COMMON blocks are if you
expect to use your program on a computer with only a FORTRAN 77
compiler (they still exist), or if it is very important that you
control the order in which your data is stored in memory.
Well, using modules is surely syntactically sweeter than using common blocks. But what are the differences in terms memory usage and allocation in both cases? Also does it make a difference in terms performance and access speed? Does that question make sense?
M.S.B. has it in his answer, but does not stress it enough in my opinion. The variables in COMMON blocks are laid out in memory exactly in the order in the definition of the block. From this the restriction, that no dynamic memory objects (allocatable, pointer) can be in a COMMON block, immediately follows.
The "sequence association" means you can count on the placement of the variables in such a way that you can, e.g., use two following arrays as a large one.
COMMON blocks have probably no place in modern code, although they are not declared obsolete.
When it comes to speed, if the variable is the same, there shouldn't be any difference in accessing it, whether it is in a module or in a COMMON block.
One difference memory-wise is that you can use allocatable arrays in modules, but not in common. (See Fortran common variables, allocatable array). Much more convenient if you have an array that you don't know the size of the array at compile time. The old FORTRAN way was to declare the array at some huge size that was hopefully large enough, but which typically wasted space. With the allocatable array you can allocate the array at the precise size needed.
I never use COMMON in new code. It is more limited and brings in the unnecessary "sequence association", i.e., associating variables by their layout in memory.

Is weak typing a performance increase or a decrease?

When writing interpreted languages, is it faster to have weak typing or strong typing?
I was wondering this, because often the faster dynamically typed interpreted languages out there (Lua, Javascript), and in fact most interpreted languages use weak typing.
But on the other hand strong typing gives guarantees weak typing does not, so, are optimization techniques possible with one that aren't possible with the other?
With strongly typed I mean no implicit conversions between types. For example this would be illegal in a strongly typed, but (possibly) legal in a weakly typed language: "5" * 2 == 10. Especially Javascript is notorious for these type conversions.
it seems to me that the question is going to be hard to answer with explicit examples because of the lack of "strongly typed interpreted languages" (using the definitions i understand from the question comments).
i cannot think of any language that is interpreted and does not have implicit conversions. and i think this for two reasons:
interpreted languages tend not be statically typed. i think this is because if you are going to implement a statically typed language then, historically, compilation is relatively easy and gives you a significant performance advantage.
if a language is not statically typed then it is forced into having implicit conversions. the alternative would make life too hard for the programmer (they would have to keep track of types, invisible in the source, to avoid runtime errors).
so, in practice, all interpreted languages are weakly typed. but the question of a performance increase or decrease implies a comparison with some that are not. at least, it does if we want to get into a discussion of different, existing implementation strategies.
now you might reply "well, imagine one". ok. so then you are asking for the performance difference between code that detects the need for a conversion at runtime with code where the programmer has explicitly added the conversion. in that case you are comparing the difference between dynamically detecting the need for a conversion and calling an explicit function specified by the programmer.
on the face of it, detection is always going to add some overhead (in a [late-]compiled language that can be ameliorated by a jit, but you are asking about interpreters). but if you want fail-fast behaviour (type errors) then even the explicit conversion has to check types. so in practice i imagine the difference is relatively small.
and this feeds back to the original point - since the performance cost of weak typing is low (given all the other constraints/assumptions in the question), and the usability costs of the alternative are high, most (all?) interpreted languages support implicit conversion.
[sorry if i am still not understanding. i am worried i am missing something because the question - and this answer - does not seem interesting...]
[edit: maybe a better way of asking the same(?) thing would be something like "what are the comparative advantages/disadvantages of the various ways that dynamic (late binding?) languages handle type conversion?" because i think there you could argue that python's approach is particularly powerful (expressive), while having similar costs to other interpreted languages (and the question avoids having to argue whether python or any other language is "weakly typed" or not).]
With strongly typed I mean no implicit conversions between types.
"5" * 2 == 10
The problem is that "weak typing" is not a well-defined term, since there are two very different ways such "implicit conversions" can happen, which have pretty much the opposite effect on performance:
The "scripting language way": values have a runtime type and the language implicitly applies semantic rules to convert between types (such as formatting a binary number as a decimal string) when an operation calls for the different type. This will tend to decrease performance since it A) requires there to be type information at runtime and b) requires that this information be checked. Both of these requirements introduce overhead.
The "C way": at runtime, it's all just bytes. If you can convince the compiler to apply an operation that takes a 4 byte integer on a string, then depending on how exactly you do it, either the first 4 bytes of that string will simply be treated as if they were a (probably very large) integer, or you get a buffer overrun. Or demons flying out of your nose. This method requires no overhead and leads to very fast performance (and very spectacular crashes).

Functional programming vs. variable and memory

Does functional programming use variables?
If no, how do the functional programs occupy memory?
Both functional programs and imperative (C#, Java) programs use variables, but they define them differently.
In functional programs the variables are like those in mathematics, once a value has been assigned the value cannot change.
In imperative languages it is typical that the values held by variables an be changed.
In both cases variables use memory.
If you're asking about implementation details for various methods of compiling functional programs, you probably need to start with reading "Implementing functional languages: a tutorial". It is a bit out of date (e.g., it does not cover the modern STG approach), but still valuable. Another, even older text to read is Field, Harrison, "Functional programming" (never mind the title, it's mostly about implementing FP compilers).
Pure functional programming uses no variables, but maybe constants in the C sense (that is, assigned only once, but at runtime).
Functional programs occupy memory with the function call "stack", i.e. the current expression and the arguments of recursively called functions.
Does functional programming use variables?
Well, at least you can bind names to values. One can call this name a variable, even if it is not variable. But in math, when we see:
x + 3 = 5
we call x a variale, though it is just another name of 2.
Otoh, the names that are bound to arguments of functions are indeed variable, if only across different invocations of the function.
If no, how do the functional programs occupy memory?
There will be language elements to construct non-primitive values, like lists, tuples, etc. Such a data constructor creates new values from old ones (somewhere in memory, but those details are irrelevant for FP).

Does over-using function calls affect performance? Specifically in Fortran

I habitually write code with lots of functions, I find it makes it clearer. But now I'm writing some code in Fortran which needs to be very efficient, and I'm wondering whether over-using functions will slow it down, or whether the compiler will work out what's going on and optimise?
I know in Java/Python etc each function is an object, and so creating lots of functions would require them to be created in memory. I also know that in Haskell the functions are reduced into each other, so it makes little difference there.
Does anyone know about the case with Fortran? Is there a difference with using intent/pure functions/declaring fewer local variables/anything else?
Function calls carry a performance cost for stack based languages, like Fortran. They have to add on to the stack and such.
Because of this, most compilers will try to inline function calls aggressively, if it is possible. Most of the time the compiler will make the right choice on whether or not to inline certain functions in your program.
This automatic inlining process will mean that there is no extra cost for writing your function (at all).
This means that you should write your code as cleanly and organized as possible, and it is likely that the compiler will do these optimizations for you. It is more important that your overall strategy for solving the problem is the most efficient than worry about performance of function calls.
Just write the code in the simplest and most well-structured way you can, then when you have it written and tested you can profile it to see if there are any hotspots which require optimisation. Only at that point should you concern yourself with micro-optimisations, and this may not even be necessary if your compiler is doing its job.
I've just spent all morning tuning an app consisting of mixed C and Fortran, and of course it uses a lot of functions. What I found (and what I usually find) is not that functions are slow, but that certain function calls (and very few of them) don't really have to be done at all. For example, clearing memory blocks, just to be neat, but doing it at high frequency.
This is not a function of language, and not really a function of inlining either. Function calls could be free and you would still have the problem that the call tree tends to be more bushy than necessary. You need to find out where to prune it. This is the "profiling" method I rely on.
Whatever you do, find out what needs to be fixed. Don't Guess. Many people don't think of this kind of question as guessing, but when they find themselves asking "Will this work, will that help?", they're poking in the dark, rather than finding out where the problems are. Once they know where the problems are, the fix is obvious.
Typically subroutine / function calls in Fortran will have very little overhead. While the language standard doesn't specify argument passing mechanisms, the typical implementation is "by reference" so no copying is involved, only setting up a new procedure. On most modern architectures this has little overhead. Selecting good algorithms is generally far more important than micro-optimizations.
An exception about calling be quick could be case in which the compiler has to create temporary arrays, for example, if the actual argument is a non-contiguous array subsection and the called procedure argument is a plain contiguous array. Suppose that the dummy argument is dimension (:). Calling it with an array of dimension (:) is simple. If you request a non-unit stride in the call, e.g., array (1:12:3), then the array is non-contiguous and the compiler may need to create a temporary copy. Suppose that the actual argument is dimension (:,:). If the call has array (:,j), the sub-array is contiguous since in Fortran the first index varies fastest in memory and shouldn't need a copy. But array (i,:) is non-contiguous and might require a temporary copy.
Some compilers have options to warn you when temporary array copies are needed so that you can change your code, if you wish.