A StrictLanguage is one that evaluates the arguments of functions before calling the function. Compare with a language that uses LazyEvaluation, where arguments aren't evaluated till needed. StrictLanguages? have the advantage that they are currently faster. LazyLanguage?s have a cleaner computational model. For example, they don't need special code to implement conditional operators.
Is 'C' a strict language?:
But is there any language that is strictly a StrictLanguage? Is 'C' a StrictLanguage - consider ((a && b ) || c )? There may be disagreement as to what constitutes a function. I regard both '&&' and 'for()' as functions, just they have slightly odd syntax. If we restrict attention to user defined functions there are still functions which, like qsort(), take a pointer to a function, only evaluating that function later.... So is 'C' a StrictLanguage?
C is a StrictLanguage. If && and for() were functions, you would be able to get a function pointer to them. Since you can't, they aren't. Conditional require LazyEvaluation to work correctly, which is why conditional operators aren't functions in a StrictLanguage. qsort() is a strict function. The pointer is evaluated to the address of the comparison function before qsort() is called. Same as in strict FunctionalProgrammingLanguage like SchemeLanguage and MlLanguage where passing functions as arguments is common practice -- NoelWelsh
I don't think being or not being able to get a pointer to the function is relevant. Suppose instead of && I write my own function called shortableAnd( func * pFunc1, func * pFunc2 ); This function only evaluates argument 2 if argument 1 evaluates to true. You can take the address of shortableAnd(), so by your definition it is a function. Now I cook the compiler slightly so that && is actually implemented via shortableAnd() behind the scenes. The compiler behaves like a C compiler (the implementation is a bit inefficient but heck we can live with that..) but your reason for rejecting && as a true function has now gone. As I see it && and qsort are now on the same footing. Have I sufficiently modifed C to stop it being a strict language? I don't think so. Saying that something is only a function if you can get a pointer to it I think is therefore a RedHerring.
C is still a StrictLanguage. Strictness is all about when arguments are evaluated, and not about the ability to pass functions as arguments. For example, if I call your shortableAnd function as follows:
shortableAnd(falseFunction, (destroyTheComputer(), trueFunction));does the computer get destroyed? Yes, in C, because destoryTheComputer() is evaluated before shortableAnd is called. In a language with LazyEvaluation the computer lives on. StructureAndInterpretationOfComputerPrograms, which is online, has a very good discussion on LazyEvaluation in chapter 4
Do SmalltalkLanguage and LispLanguage count as StrictLanguages?
Yes
Syntax for Laziness
The page on LazyEvaluation argues whether or not LazyEvaluation MUST incur a significant run time overhead. I'll leave that argument to that page. (See StrictnessAnalysis for further discussion) If some cool compiler could make that overhead comparable, say, to compiling from tokenized source code, I'd still see LazyEvaluation languages like HaskellLanguage and CleanLanguage taking second place on the podium. What seems to me to be missing is a combination of internal LazyEvaluation - which makes the compiler design clean and flexible - with an external presentation that is more C like - SyntacticSugar. There have been attempts, but none has yet caught on in a really big way.
Q: The syntax problem that is crying out for a cleaner solution is how in a 'C' like environment to distinguish between calling a function on the result of another function and calling a function to operate on a function as an argument. If we were extending C to do this, what would be a good choice of syntax?
As in FunctionalProgrammingLanguage, you must be able to distinguish between a function as a value, and applying that function to some arguments. E.g:
qsort evaluates to the qsort function
qsort(arg1, arg2, arg3) evaluates to application of the qsort function to the given arguments.
I humbly suggest you look at FunctionalProgrammingLanguage and LispMacros. This problem has been addressed by a lot of researchers and elegant solutions have been found to the above problems. -- NoelWelsh
In SmalltalkLanguage, strictness vs. laziness is fully explicit. All message sends are strict, there is only one lazy construct: making a block. Thus in something like:
object1 isNil or: [object2 isNil], it is explicit that object1 isNil is passed strict and object2 isNil is passed lazily.
Operator&& vs && and other variations
In C++ '||' and '&&' are functions: operator||(a,b) and operator&&(a,b). All the operatations of the language are really syntatic shortcuts for functions.
But that does bring up an interesting question: I don't know how the C/C++ "shortcut evaluation" rules interact with the function syntax of "operatorXX()" definitions. Normally, all arguments are evaluated before calling a function. -- JeffGrigg
It's true you can define your own '||' and '&&' functions, but these functions have StrictEvaluation, not the LazyEvaluation that the built in functions have. So the built ins are special cases, and C++ is still a StrictLanguage. -- NoelWelsh
What about if you use 'inline' with your operator&&() definition? If your user defined '&&' uses an if(), shouldn't the compiler be smart enough to NOT to evaluate the second argument if it doesn't need to, or is this possibility nailed by the LanguageLawyers?
I don't know if the language allows what you suggest. If it does then effectively you're writing a macro. LispMacros are commonly used by Lisp hackers to add new control structures to the language. I feel it's better to add a well thought out macro system (say, with hygenic macros like DefineSyntax that is provided by the SchemeLanguage) then abuse function inlining to fake macros. -- NoelWelsh
Inline functions are supposed to have the same behavior as normal functions; they're not macros. So all arguments must be evaluated before checking the "inlined" code. -- JeffGrigg