Do we still need subroutines? [closed] - fortran

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
In Fortran, a clear difference exists between function and subroutine: functions return one value, subroutines return no value. This introduce a cascade of differences between the two. One example is the calling semantics: you can call a function just as in other languages, but in order to call a subroutine you must issue a call statement first.
With the addition of pointers and data types in Fortran95, it appears that there is no technical limitation in making any subprogram a function, and keeping subroutines just for legacy. Functions could return zero (you just return a dummy integer), one, or multiple values (for example, you could return a pointer to an allocated instance of a type, like a C++ STL Pair).
Am I wrong? Do we still need subroutines in Fortran programming due to some feature that subroutines have and functions don't?

If you search the comp.lang.fortran archives, you'll find discussions about the semantics of functions. IIRC it turns out that it's not clearly specified in the standard what is and what isn't allowed for functions that have side-effects.
For instance, can the compiler optimize
x = foo(args) + foo(args)
into
x = 2 * foo(args)
Or for another example, consider
x = y + foo(y)
What if foo() changes the value of y? Remember that Fortran doesn't have the C concept of sequence points.
In general, the recommendation by several experts is to use functions only if they're pure, otherwise use subroutines. And, that is advice that I follow myself as well.

I don't think subroutines are going anywhere. Most other languages allow methods that do and do not return values. I can't see any reason why that's a bad thing. No one should be moved to change a thing.
Legacy alone says that subroutines will persist as long as Fortran does. And as long as Fortran is around, there'll be nothing wrong with writing a method that performs an action and returns nothing.
UPDATE:
Why do you say "hassle"? What's the big deal? I disagree with the idea that subroutines are a "hassle" when they're used in an appropriate situation.
Fortran has maintained a distinction between functions and subroutines since version 77 and probably earlier. Other C-family languages do, too. Why is this suddenly such a hassle? Even the languages that have had pointers and objects for a long time have methods that return void.

You're trying to program C in fortran again, aren't you? ;-)
In my opinion, yes - we do. For if for one reason only - they're easier to grasp, to understand, and they're more widely used than functions.
Also, -1, for I believe this is not a constructive question. If you don't like them, then don't use them.

If I understand correctly Stefano is not against the idea of subroutines. The opinion against them is nonsense. He against the usage of different styles for subroutines/functions.
Fortran is imperative programming language. More precisely it is a procedural programming language (and even more precisely it is structured programming language).
In imperative programming we have a state and statements to change it. In procedural programming our tools to do changes are procedures (we localize changes inside procedures). The procedure may or may not return some value. And I don't think that this fact (either procedure return value or not) is so significant reason to have 2 different entities in the programming language. We can have only functions (like in C) and just return something special when we do not actually need to return something (void). Or we can have only procedures and special syntax permitting to return values like in Modula-2, Oberon, ...
The language probably should have only one style to declare procedures. I agree with You, Stefano.

The fact that I have to answer myself to this question is insane, but that's how it is.
The difference stems from the fact that you cannot "call functions like in other languages" in Fortran. While in C you can call an integer function without assigning the value, example
int foo() {
return 5;
}
int main() {
foo(); // this works
}
In Fortran, you always have to associate a receiving variable. Example
module test
implicit none
contains
integer function foo()
print *, "hello"
foo = 0
end function
end module
program hello
use test
integer :: x
x = foo() ! this works
foo() ! this does not compile
end program hello
Meaning that to "emulate" a void function by returning a dummy integer would still not allow you to call without having a receiver variable.
In Fortran, the void return type does not exist. Technically, you could structure your program with all functions, replace every occurrence of the call statement with x = like seen above, but that would not make your syntax similar to C or other languages anyway, where there is no distinction between void-returning functions and non-void returning functions. subroutines are the only entities that allow to "return void", but the semantic to perform the call is simply different. Apart from that, there's no difference between the two.

Related

Why is C++'s void type only half-heartedly a unit type?

C++'s void type is not uninhabited. The problem is that while it has precisely one inhabitant, very much like the Unit type (a.k.a. ()) in ML-like languages, that inhabitant cannot be named or passed around as an ordinary value. For example, the following code fails to compile:
void foo(void a) { return; }
void bar() { foo(foo()); }
whereas equivalent (say) Rust code would compile just fine:
fn foo(a : ()) { return; }
fn bar() { foo(foo(())); }
In effect, void is like a unit type, but only half-heartedly so. Why is this the case?
Does the C++ standard explicitly state that one cannot create values of type void? If yes, what is the rationale behind this decision? If not, why does the code above not compile?
If it is some backwards-compatibility related reason, please give a code example.
To be clear, I'm not looking for work-arounds to the problem (e.g. using an empty struct/class). I want to know the historical reason(s) behind the status quo.
EDIT: I've changed the syntax in the code examples slightly to make it clear that I'm not trying to hijack existing syntax like void foo(void) (consequently, some comments may be out of date). The primary motivation behind the question is "why is the type system not like X" and not "why does this bit of syntax not behave as I'd like it to". Please keep this point in mind if you're writing an answer talking about breaking backwards compatibility.
"Does the C++ standard explicitly state that one cannot create values of type void?"
Yes. It states that void is an incomplete type and cannot be completed. You can't create objects or values with an incomplete type.
This is an old rule; as the comments note it's inherited from C. There are minor extensions in C++ to simplify the writing of generic code, e.g. void f(); void g() { return f(); } is legal.
There seems to be little gain in changing the status quo. C++ is not an academic language. Purity is not a goal. Writing useful program is, but how does such a proposal help with that? To quote Raymond Chen, every proposal starts at -100 and has to justify its addition; you don't justify the lack of features.
That is really an historical question. Old (pre-C) language used to differentiate functions which returned values, from subroutines which did not (ooh, the good old taste of Fortran IV and Basic...). AFAIK, early C only allowed functions, simply functions were by default returning int and it was legal to have no return statement (mean return an unspecified value) and legal to ignore any return value - so that the programmer can write coherent code... In those early days, C was used more or less as a powerful macro assembler, and anything was allowed provided the compiler can translate it into machine instructions (no strict aliasing rule for example...). As the memory unit was char, no need for void * pointer, char * was enough.
Then people felt the need to make clear that a buffer was expected to contain anything and not a character string, and that some functions will never return a value. And void came to feel the gap.
The drawback, is that when you declare a void function, you declare what was called a subroutine, that is something that can never be used as a value, in particular never be used as a function parameter. So void is not only a special type that can never be instantiated, it really declare that the result cannot be a member of an expression.
And because of language inheritance, and because the C standard library is still a subset of the C++ standard one, C++ still processes void the way ANSI C did.
Other languages can use different conventions. In Python for example a function will always return something, simply it returns the special None value if no return statement is encountered. And rust seem to have still another convention.

Is a function without input/output a procedure? [duplicate]

This question already has answers here:
What is the difference between a "function" and a "procedure"?
(18 answers)
Closed 8 years ago.
I read many many articles about difference between function and procedure but there is something I'm in doubt about.
Do we call following statement a function or a procedure in terminology?
void f() { return; }
Some articles says function returns value but procedure does not.
Some other article says if a function returns one value called function but if it returns more than one value it called procedure.
In the standard terminology of C and C++, no. It's a function whether or not it returns anything, or even if it doesn't return.
In more general computing vocabulary, and the terminology of other programming languages, it might be called a "procedure" or a "subroutine" (and perhaps a few other terms) if it doesn't return a value.
A procedure is a function that do not return a result!
There is no such term as procedure in C and C++ languages. So relative to C and C++ languages your question has no sense. In any other languages the definition of the term procedure can vary.
In C and C++ statement
void f() { return; }
is a function definition.
As Mike annd Grzegorz says, from C Standard point of view there is no difference, but the function term is used by convention.
In other programming language (e.g. basic) that distinction is commonly used depending if return or not a value that function.
As final note: in the C Programming Language book (official C programming language book) from Dennis Ritchie (C creator) the term function is used independently if returns or not a value and that's one of the reason that the term is used indistinctly.
There are various terminologies that means the same in various different languages. Like function used in structured language like c, Method's used in java, procedure, function both used in Scala.
In reality, Procedure is a function really but that doesn't return anything and in C we still refer to it as function.
From the C Standard point of view there is no distinction between functions and procedures (like in e.g. Pascal) or subroutines (like in e.g. Fortran). Both types (i.e. returning void and non-void) are simply named as functions. I believe that C++ just follows this way.

Member functions for scalar types and operator overloading [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I've been thinking about some possible features C++ could have, does anyone know why they aren't supported?
Member functions for built-in types. This may just not seem necessary, but an interesting feature nonetheless. Example pseudocode: int int::getFirstBit(void) {return *this & 1;} ... int a = 2; a.getFirstBit(); This may seem useless, but it shouldn't be hard to implement either. With this springs up the following thought:
Member functions outside class definition. I don't see why this shouldn't be supported, except for conflicts with access restriction (public,protected,private,etc.) and encapsulation, but perhaps only structs could have this feature.
Operator overloading for non-object types, a use for this could be for pointers or arrays.
I know these features aren't necessary for much, but they still seem cool. Is it because they don't seem necessary or because they can cause many headaches?
I know these features aren't necessary for much, but they still seem cool. Is it because they don't seem necessary or because they can cause many headaches?
Part of one part of the other. Every new feature that is added to a language increments the complexity of the language, compilers and programs. In general, unless there is a real motivating need (or the new feature will help in writing simpler safer programs) features are not added.
As of the particular features you suggest:
1- Member functions for built in types
There is no need, you can do anything you want to do with a member function with a free function for the same cost and with the only difference in user code that the argument to the function is before a . or inside the parenthesis.
The only thing that cannot be done with free functions is dynamic dispatch (polymorphism) but since you cannot derive from those types, you could not have polymorphism either. Then again, to be able to do this you would need 2.
2- Member functions outside class definition.
I understand that you mean extension methods as in C#, where new methods can be added to a type externally. There are very few uses of this feature that are not simple enough to implement without it. Then there are the complexities.
Currently, the compiler sees a single definition of the class and is able to determine all member methods that can be applied to an element of the type. This includes virtual functions, which means that the compiler can at once determine the virtual function table (while vtable is not standard, all implementations use them). If you could add virtual methods outside of the class definition, different translation units would be seeing different incompatible view of the type. Dispatching to the 3rd virtual function could be calling foo in one .cpp file but bar in another. Solving this without postponing a big part of the linking stage to the loading of the binary into memory for execution would be almost impossible, and postponing it would mean a significant change in the language model.
If you restrict the feature to non-virtual functions, things get simpler as the calls would be dispatched to the function directly, but nevertheless, even this would imply other levels of complexity. With a separate compilation model as in C++, you would end up having to write headers for the original class and the extension methods, and including both in the translation unit from which you want to use it, which in most cases you can simplify by just declaring those same methods in the original headers as real member methods (or free functions, free functions do form part of the interface of user defined types!)
Additionally, allowing this would mean that simple typos in the code could have unexpected results. Currently the compiler verifies that the definition of a member function has a proper declaration, if this was allowed that check would have to be removed, and a simple typo while writing the name in either the declaration or definition would cause two separate functions rather than a quick to fix compiler error.
3- Operator overloading for non-object types
The language allows for overloading of operators for all user defined types, which includes classes and enumerations. For the rest of the types, there is a set of operators that are already defined with precise semantics that cannot be changed. Again with separate compilation model, it would mean that 1+2 could mean different things in different translation units, in particular the exact combination of includes could change the semantics of the program, and that would cause havoc --you remove a dependency in your header, and that removes an include that contains the overload for const char* + int, which in turn means that the semantics of "Hi" + 2 in code that included your header changes, from the user defined operation to yielding a pointer to the nul terminator of the string. This is really dangerous, because it means that a simple change in one part of a program can render other parts of the program incorrect.
Even for combinations for which there is no current meaning (char* + int*) you can use a regular function to provide the same operation. Remember that you should only overload an operator when in the domain that you are modeling that operation is naturally understood to have that particular semantics, which is why you can overload for user defined types, but pointers are not part of your domain, but rather part of the language, and in the language there is no natural definition of what "Hi" + new int(5) means. Operator overloading has the purpose of making code more readable and in any context for which there is no natural definition, operator overloading has the exact opposite effect.
Because you can write a free function that does the same thing. Would the "member function" be so much more desirable so as to offset the tremendous cost of ratifying this in the standard and having compiler vendors implement it? No.
Outside where exactly?
See 1.

How does calling a method in Objective-C differ from C++? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Objective C message dispatch mechanism
My question IS NOT about the syntax. I'd like to learn how is calling a method in C++ different from sending a message to an object in Objective-C and how they are performed?
This is quite a complicated question, as there is no fix C++ calling convetion unlike C.
Objective-C is just a thin wrapper around C, so it uses the same convention.
Just one additional thing to now, when you send a message like:
[target selector];
It is the same as:
objc_msgSend(target, #selector(selector));
Then it's just the traditional C calling convention, with a first table lookup for the function matching your message. The objc_msgSend is a bit more complicated as it keeps the arguments stack in place and pass it directly to the underlying function.
The C++ calling convention differs from one name-mangling to another, and even from one compiler to another.
From a performance point of view, C++ method call is faster as the link is resolved at compile-time (more exactly at link-time). The method either exists or not, which cause a linker error.
Objective-C method call include a method table lookup at runtime, thus your method may be added later in your code, which gives more flexibility but less performance.
Entirely the same and entirely different. In C++ you'd say
result = myObjectPtr ->myMethod(myParm1, myParm2);
In Objective-C you'd say
result = [myObjectPtr myMethodWithParm1:myParm1 andParm2:myParm2];
In the simple case they'd function the same, from an external appearances standpoint, but lots of differences at the implementation level, since Objective-C calls are dynamic.
It would take several pages to enumerate all the differences in any detail (though for the simplest cases the differences aren't significant).

why wasn't the idea of nested functions, implemented in older c++ standard?

was the idea of nested functions considered to be useless during the time of developing older c++ standard, because its usage is basically covered by another concept like object-oriented programming; or it wasn't implemented just as a matter of simplification?
Nested functions - to be useful - need the stack frame of the containing function as context. Look at this:
class Foo()
{
void Tripulate()
{
int i=0;
void Dip()
{
// ...
}
int x = 12;
for(i=1; i<=3; ++i)
{
int z= 33;
Dip();
// ...
}
}
}
Which values should Dip() get access to?
None? you have just duplicated the functionality of (anonymous) namespaces, more or less.
Only to i, because it's the only one defined before the function?
Only to i and x, because they are in the sam scope as Dip()? Does the compiler have to make sure the constructor of x did already run, or is that your job?
What about z?
If Dip gets any access to both the local values of tripulate and the stack frame, so the internal prototype would be
void Dip(Foo * this, __auto_struct_Dip * stackContext)
{
// ...
}
You have basically replicated the functionality of structs / classes and member functions, but on two incompatible and non-exchangable paths. That's a lot of complexity for a questionable gain.
I've wished for local functions a few times, simply because this would better indicate the scope where this is needed. But with all the questions... there are more useful things to throw more complexity onto C++.
[edit] With C++0x, lambdas can do that, allowing to explicitly state what they capture.
The idea was raised (a number of times) during standardization. Steve Clamage wrote a post in comp.std.c++ in 1996 responding to a question about adding them to C++. He summarized his points as:
In the end, it seems to me that nested functions do not solve any
programming problem for which C++ does not already have a solution at
least as good.
A proposal to add nested functions to C++ should show an important
class of programming problems solved by nested functions which are
inconvenient to solve otherwise. (Perhaps there are such problems, and
I simply haven't seen them.)
A later (1998) post by Andrew Koenig indirectly states that the committee did discuss it, but nothing seems to have materialized from it.
The obvious way to support nested functions requires hardware support, and still adds a bit of overhead. As pointed out in a post by Fergus Henderson, it's also possible to support them via "trampoline" code, but this method adds some compiler complexity (even if they're never used).
As an aside: all three are members of the C++ standard committee (or at least were at the time). If memory serves, at that time Steve was either convener of the ISO committee or chairperson of the US committee.
You don't really need them - you can simply use static functions to accomplish the same thing. Even when programming in languages that do support nested functions, like Pascal, I avoid them because (to me at least) they make the code more complex and less readable.
You can either use a nested class having the method you need. In C++ the idea is to group methods together with data to get classes and not having loose functions around.