MsgBox "" vs MsgBox() in VBScript - function

I'm trying to write a VBScript and I'm using functions such as Randomize, and MsgBox. I'm curious as to what is the difference of using () and not using them. For example:
Randomize - This line works.
Randomize() - This line works also.
MsgBox "Hello, World!" - This works.
MsgBox ("Hello, World!") - This works as well.
The script will be running on multiple machines with different versions of Windows (at least Windows XP). I'm wondering if I would be getting any compatibility/syntax issues in using these functions.

A callable piece of code (routine) can be a Sub (called for a side effect/what it does) or a Function (called for its return value) or a mixture of both. As the documentation for MsgBox,
Displays a message in a dialog box, waits for the user to click a
button, and returns a value indicating which button the user clicked.
MsgBox(prompt[, buttons][, title][, helpfile, context])
indicate, this routine is of the third kind.
The syntactical rules of VBScript are simple:
Use parameter list () when calling a (routine as a) function
If you want to display a message to the user and need to know the user's response:
Dim MyVar
MyVar = MsgBox ("Hello, World!", 65, "MsgBox Example")
' MyVar contains either 1 or 2, depending on which button is clicked.
Don't use parameter list () when calling a (routine as a) Sub
If you want to display a message to the user and are not interested
in the response:
MsgBox "Hello, World!", 65, "MsgBox Example"
This beautiful simplicity is messed up by:
The design flaw of using () for parameter lists and to force call-by-value semantics
>> Sub S(n) : n = n + 1 : End Sub
>> n = 1
>> S n
>> WScript.Echo n
>> S (n)
>> WScript.Echo n
>>
2
2
S (n) does not mean "call S with n", but "call S with a copy of n's value".
Programmers seeing that
>> s = "value"
>> MsgBox(s)
'works' are in for a surprise when they try:
>> MsgBox(s, 65, "MsgBox Example")
>>
Error Number: 1044
Error Description: Cannot use parentheses when calling a Sub
The compiler's leniency with regard to empty () in a Sub call. The 'pure'
Sub Randomize (called for the side effect of setting the random seed) can be called by
Randomize()
although the () can neither mean "give me your return value) nor "pass
something by value". A bit more strictness here would force programmers to be aware of the difference in
Randomize n
and
Randomize (n)
The Call statement that allows parameter list () in Sub calls:
>> s = "value"
>> Call MsgBox(s, 65, "MsgBox Example")
which further encourage programmers to use () without thinking.
(Based on What do you mean "cannot use parentheses?")

To my knowledge, these are the rules for calling subroutines and functions in VBScript:
When calling a subroutine or a function where you discard the return value, don't use parentheses
When calling a function where you assign or use the return value, enclose the arguments in parentheses
When calling a subroutine using the Call keyword, enclose the arguments in parentheses
Since you probably won’t be using the Call keyword, you only need to learn the rule that if you call a function and want to assign or use the return value you need to enclose the arguments in parentheses. Otherwise, don't use parentheses.
Here are some examples:
WScript.Echo 1, "two", 3.3 - calling a subroutine
WScript.Echo(1, "two", 3.3) - syntax error
Call WScript.Echo(1, "two", 3.3) - keyword Call requires parentheses
MsgBox "Error" - calling a function "like" a subroutine
result = MsgBox("Continue?", 4) - calling a function where the return value is used
WScript.Echo (1 + 2)*3, ("two"), (((3.3))) - calling a subroutine where the arguments are computed by expressions involving parentheses (note that if you surround a variable by parentheses in an argument list it changes the behavior from call by reference to call by value)
WScript.Echo(1) - apparently this is a subroutine call using parentheses, but in reality, the argument is simply the expression (1), and that is what tends to confuse people that are used to other programming languages where you have to specify parentheses when calling subroutines
I'm not sure how to interpret your example, Randomize(). Randomize is a subroutine that accepts a single optional argument, but even if the subroutine didn't have any arguments, it is acceptable to call it with an empty pair of parentheses. It seems that the VBScript parser has a special rule for an empty argument list. However, my advice is to avoid this special construct and simply call any subroutine without using parentheses.
I'm quite sure that these syntactic rules applies across different versions of operating systems.

You are just using a single parameter inside the function, hence it is working fine in both the cases, like follows:
MsgBox "Hello, World!"
MsgBox ("Hello, World!")
But when you'll use more than one parameter, in VBScript a method with parentheses will throw an error and without parentheses will work fine like:
MsgBox "Hello, World!", vbExclamation
The above code will run smoothly, but
MsgBox ("Hello, World!", vbExclamation)
will throw an error.
Try this!! :-)

You have to distinguish between subroutines and functions in VBA... Generally (as far as I know), subroutines do not return anything and the surrounding parentheses are optional. For functions, you need to write the parentheses.
As for your example, MsgBox is not a function but a subroutine and therefore the parentheses are optional in that case. One exception with functions is, when you do not assign the returned value, or when the function does not consume a parameter, you can leave away the parentheses too.
This answer goes into a bit more detail, but basically you should be on the save side, when you provide parentheses for functions and leave them away for subroutines.

Related

Replacement for obsolete "statement functions" in Fortran 95 and later?

Original Question
As I understand, as of Fortran 95 Statement functions have been declared obsolete in favor of internal functions. However, internal functions do not cover all use-cases, in particular when using statement functions as abbreviations with implied arguments for making the implementation of long formulas more readable. Is there any adequate replacement for this usecase?
Example
E.g., lets say we have an relation
Cᵢⱼ = ∫dx₁∫dx₂∫dx₃∫dy₁∫dy₂∫dy₃ (AᵢⱼBᵢⱼ +BᵢⱼAⱼᵢ)
E.g. compare an implementation using directly the internal representation of A,B with the index-order mandated by prior code, resulting in
do a1=1,NGRID1; do a2=1,NGRID2; ...; do aN=1,NGRIDN
x(i,j) = x(i,j) &
& + ARR_A(x1,x2,x3,i,y1,y2,y3,j)*ARR_B(x1,x2,x3,i,y1,y2,y3,j) &
& + ARR_B(x1,x2,x3,i,y1,y2,y3,j)*ARR_A(x1,x2,x3,i,y1,y2,y3,j)
end do; end do; ...; end do
to an implementation using statement functions as abbreviation,
A(i,j) = ARR_A(x1,x2,x3,i,y1,y2,y3,j)
B(i,j) = ARR_B(x1,x2,x3,i,y1,y2,y3,j)
...
do x1=1,NGRID1; do x2=1,NGRID2; ...; do y3=1,NGRIDN
x(i,j) = x(i,j) + A(i,j)*B(i,j) + B(i,j)*A(i,j)
end do; end do; ...; end do
In the second version it seems much easier to spot the mixed-uo order of the indices after noticing that there is an issue.
Using macros?
The only method to achieve similar semantics I found was using preprocessor macros. Typically, C-style macros are used, which here would lead to
#define A(i,j) ARR_A(x1,x2,x3,i,y1,y2,y3,j)
but this sacrifices scoping of the name. While this seems potentially useful, especially when the same abbreviation is used accross multiple functions, it seems potentially rather confusing. For a start, the compiler will give more useful error messages, when using statement functions incorrectly than it can for macros.
It also introduces the need to manually #undefine the name, if we want to reuse the same name in different contexts for different things.
Solution (1)
I had misunderstood how CONTAINS and internal functions work (see IanH's answer and its comments).
Short: Internal functions can be defined inside subroutines with CONTAINS, and work exactly like statement functions, except for a more verbose syntax.
The misunderstanding arose partly because it apparently is not allowed to define a subroutine inside a subroutine in this manner. Apparently it does work. No idea what I was doing wrong.
Internal procedures are pretty much a drop-in replacement for statement functions for this use case, with their usual benefits of more capability and less proneness to error, at the cost of some slight extra verbosity with their definition.
MODULE some_module ! Just for the sake of example.
...
CONTAINS
! The host of the internal procedure. This could
! also be an external procedure or a main program.
! It could also be a function.
SUBROUTINE some_subroutine
...
DO i = 1, 3
DO j = 1, 3
DO x1 = 1, 3
DO x2 = 1, 3
...
x(i,j) = x(i,j) + A(i,j)*B(i,j) + B(i,j)*A(i,j)
...
END DO
END DO
END DO
END DO
...
CONTAINS
! An internal procedure. For different use cases
! this could also be a subroutine.
FUNCTION A(i,j)
INTEGER, INTENT(IN) :: i,j
REAL :: A
A = ARR_A(x1,x2,x3,i,y1,y2,y3,j)
END FUNCTION A
FUNCTION B(i,j)
INTEGER, INTENT(IN) :: i,j
REAL :: B
B = ARR_B(x1,x2,x3,i,y1,y2,y3,j)
END FUNCTION B
...
END SUBROUTINE some_subroutine
...
END MODULE some_module
Note that the maximum array rank under the rules of Fortran 77/90/95/2003 is seven.

Perl: prototype in anonymous subroutine

I am currently learning about Perls system of typeglobs and namespaces. So I wrote a module that takes two arguments the value and the name of a constant and exports the constant to the caller. The $package variable is equal to caller[2].
*{"$package::$name"} = sub () { return $value; };
This code above does the job of exporting a anonymous subroutine into the callers symboltable. Because my goal is to build my own constant-implementation the subroutine has a empty prototype which means its a read-only subroutine.
But this is my problem: the prototype does not work. So
print &TestConst; #works well
print TestConst(); #works well
print TestConst; #Name "main::TestConst" used only once: possible typo at testscript.pl line 7.
Is there something wrong in my thoughts? Is there another way of doing it?
You can define all the symbols you want during runtime, but prototypes will only affect code compiled afterwards since prototypes affect how calls to the sub are parsed and compiled. For example:
use strict;
use warnings;
package Foo;
BEGIN {
*Foo::bar = sub () { 42 };
}
*Foo::baz = sub () { 43 };
my $bar = bar;
my $baz = baz;
print "bar = [$bar], baz = [$baz]\n";
If we run this, it dies with:
Bareword "baz" not allowed while "strict subs" in use at tprot.pl line
13.
That's a compile-time error caused by strict: the compiler saw the symbol baz and didn't know what it was, because the typeglob *Foo::baz does not get altered until runtime. But bar worked fine because it was defined in a BEGIN block, which executes immediately during compilation.
IOW, because barewords are ambiguous, Perl needs to know at compile-time whether it's a sub or something else. So you can install these during import (which executes in an implicit BEGIN block) but not at runtime.
Additionally, prototypes affect compilation semantics; a constant subroutine (like those made by constant.pm) gets optimized away. Other prototypes cause the parser to change its behavior (e.g. subs which can take code blocks.) The compiler has to know about all this stuff before calls to the sub are actually encountered in the code, so they can be parsed correctly. The code runs after everything is already parsed.
Calling a sub with explicit parens or with an ampersand does not have this restriction because Perl is smart enough at runtime to know that these are subroutine calls, and to look them up dynamically in the symbol table.

OCaml syntax error in function

I have to create a function which will display each element from a set of strings. I did the following:
module S = Set.Make(String);;
module P = Pervasives;;
let write x = (
P.print_string("{"); let first = true;
S.iter (fun str -> (if first then () else P.print_string(","); P.print_string(str))) x;
P.print_string("}");
P.print_newline
);;
^
At the end of the program (where I placed that sign) it appears I have an error: Syntax error: operator expected.
Please help me solve this.
I believe your syntactic problem is with let. Except in top-level code (outermost level of a module), let must be followed by in.
There are many other problems with this code, but maybe this will let you find the next problem :-)
A few notes:
Variables in OCaml are immutable. So your variable named first will always be true. You can't change it. This (seemingly minor) point is one of the keys to functional programming.
You don't need to reference the Pervasives module by name. That's why it's called "pervasive". You can just say print_string by itself.
Your last call to print_newline isn't a call. This expression just evaluates to the function itself. (You need to give it an argument if you want to call the function.)
Try replacing the semicolon after the let first = true with the keyword in.

Is the Macro argument a function?

I am trying to determine whether a given argument within a macro is a function, something like
(defmacro call-special? [a b]
(if (ifn? a)
`(~a ~b)
`(-> ~b ~a)))
So that the following two calls would both generate "Hello World"
(call-special #(println % " World") "Hello")
(call-special (println " World") "Hello")
However, I can't figure out how to convert "a" into something that ifn? can understand. Any help is appreciated.
You might want to ask yourself why you want to define call-special? in this way. It doesn't seem particularly useful and doesn't even save you any typing - do you really need a macro to do this?
Having said that, if you are determined to make it work then one option would be to look inside a and see if it is a function definition:
(defmacro call-special? [a b]
(if (#{'fn 'fn*} (first a))
`(~a ~b)
`(-> ~b ~a)))
This works because #() function literals are expanded into a form as follows:
(macroexpand `#(println % " World"))
=> (fn* [p1__2609__2610__auto__]
(clojure.core/println p1__2609__2610__auto__ " World"))
I still think this solution is rather ugly and prone to failure once you start doing more complicated things (e.g. using nested macros to generate your functions)
First, a couple of points:
Macros are simply functions that receive as input [literals, symbols, or collections of literals and symbols], and output [literals, symbols, or collections of literals and symbols]. Arguments are never functions, so you could never directly check the function the symbol maps to.
(call-special #(println % " World") "Hello") contains reader macro code. Since reader macros are executed before regular macros, you should expand this before doing any more analysis. Do this by applying (read-string "(call-special #(println % \" World\") \"Hello\")") which becomes (call-special (fn* [p1__417#] (println p1__417# "world")) "Hello").
While generally speaking, it's not obvious when you would want to use something when you should probably use alternative methods, here's how I would approach it.
You'll need to call macroexpand-all on a. If the code eventually becomes a (fn*) form, then it is guaranteed to be a function. Then you can safely emit (~a ~b). If it macroexpands to eventually be a symbol, you can also emit (~a ~b). If the symbol wasn't a function, then an error would throw at runtime. Lastly, if it macroexpands into a list (a function call or special form call), like (println ...), then you can emit code that uses the thread macro ->.
You can also cover the cases such as when the form macroexpands into a data structure, but you haven't specified the desired behavior.
a in your macro is just a clojure list data structure (it is not a function yet). So basically you need to check whether the data structure a will result is a function or not when it is evaluated, which can be done like show below:
(defmacro call-special? [a b]
(if (or (= (first a) 'fn) (= (first a) 'fn*))
`(~a ~b)
`(-> ~b ~a)))
By checking whether the first element of the a is symbol fn* or fn
which is used to create functions.
This macro will only work for 2 cases: either you pass it a anonymous function or an expression.

Matlab/Octave function handlers and nargin

I am writing program in Octave and I encountered a problem, I implemented Gauss-Legandre Quadrature and I pass to my Gauss-Legandre function few arguments, and I pass the function to be intergrated in a cell cube, so I can pass few function at a time. I have this piece of code:
for weight=1:length(w)
temp=1;
for fun=1:length(c)
%liczenie iloczynu f(x_i)g(x_i), x_i - pieriwastki wielomianu Legandra
f=c{fun};
nargin(func2str(c{fun}))
if (nargin (func2str(c{fun})) == 1)
disp('a');
temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2);
else
(b-a)/2 * x(weight) + (a+b)/2;
temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points);
end
end
%mnozenie wyniku przez odpowiedni wspolczynnik - wage
temp*=w(weight);
result+=temp;
end
In cell array there are function handlers to functions which I want to integrate. Depending on number of arguments that function takes i want to use two different calls for function. If in cell array there is handler to a function that is written in .m file in the same directory as my Octave working directory everything works fine, but when i define function in Octave running time, for example:
function result=a(x)
result=x*x
end
Type
c{1}=#a
and pass this cell array to my function Kwadratury there is an error of nargin
error: nargin: invalid function
error: called from:
Why is that and how can I solve it, so I can define function not only in .m files but also in Octave.
I suspect I have a solution, but as this is Octave-specific and I'm mostly used to MATLAB, your mileage may vary.
You call the nargin function by supplying a string argument, this means that nargin will have to resolve that function and check the number of arguments. When you declare a function in-line, that function is defined within that scope (i.e. your base scope), so resolving the function name will not work from within any function (or it might resolve to a built-in function, which is even worse behavior).
The best solution is to use nargin(c{fun}) instead of nargin(func2str(c{fun})). That way you pass the actual function handle along, and there is no need to resolve the function name to the actual function, and hence no possible ambiguity.
In general I recommend against using strings to pass functions: that why function handles are included in MATLAB, so anyone reading your code (or a static code analysis tool) will be able to understand you are working with functions. When using strings, everything becomes ambiguous: does a string 'a' refer to the function a or to the first letter in the alphabet?
With regard to using inline functions, I don't know whether Octave supports this, but if you function is quite simple, it's easier to define an anonymous function, such as your example, by a = #(x)(x*x);. That is a construct that is supported by MATLAB, so that makes your code more portable to other environments (well, you'd still need to replace X *= A with X = X * A; to be MATLAB compatible).
edit:
Another possibility could be to just try out whether a form with multiple parameters works and fall back to the one parameter form when necessary:
try
(b-a)/2 * x(weight) + (a+b)/2;
temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points);
catch ME
try
disp('a');
temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2);
catch ME
end
end
You might want to check whether the returned error ME really states that a wrong number of arguments is used to allow other errors through. I do admit this is an ugly work-around, but since Octave apparently doesn't support function handles for nargin, it might be the only way you'd get what you want for inline functions.