I would like to call more than 3 methods in the same method. Let's say that I want to set three different variables of an object with three different "set" method.
What is the best way to do it?
I tried with "and" but it doesn't seem to work.
In OCaml, ";" is the sequence operator. Expression "a; b" evaluates expression a, discards its result (which should be unit), evaluates b, then returns the result of b.
In OCaml, a function call or a method call is nothing but an expression.
So, you can write something like this:
method my_method =
my_object#set_x 10;
my_object#set_y 50;
my_object#set_z 30
Related
I've just had an irritating 30 minutes on a "compiler error" in VBA (Access 2003) caused by my use of parenthesis around the arguments I'm passing to a Sub I defined.
I've been searching to find a decent article/tutorial/instruction as to when parenthesis are necessary/appropriate/inappropriate/forbidden, but can't find any clear guidelines.
There is perfect logic to the Parentheses Rule in VB(A), and it goes like this.
If a procedure (function or sub) is called with arguments, and the call is on a line with other statements or keywords, the arguments must be enclosed in parentheses. This to distinguish the arguments belonging to the procedure call from the rest of the line. So:
1: If CheckConditions(A, B, C) = DONT_PROCEED Then Exit Sub
is a valid line; the call to CheckConditions needs the parentheses to indicate what other bits of the line are its arguments. Conversely, this would produce a syntax error:
2: If CheckConditions A, B, C = DONT_PROCEED Then Exit Sub
Because it is impossible to parse.
With a procedure call as the only statement on the line, parentheses aren't needed because it is clear that the arguments belong to the procedure call:
3: SaveNewValues Value1, Value2, Value3
While this results in a syntax error (for sound reasons discussed below):
4: SaveNewValues(Value1, Value2, Value3)
To avoid confusion about parentheses or no parentheses (in fact, to avoid the Parentheses Rule entirely), it is always a good idea to use the Call keyword for calls like these; that ensures that the procedure call is not the only statement on the line, thus requiring parentheses:
5: Call SaveNewValues(Value1, Value2, Value3)
So if you get in the habit of preceding self-contained procedure calls with the Call keyword, you can forget the Parentheses Rule, because you can then always enclose your arguments in parentheses.
The matter is confused by the additional role parentheses play in VB(A) (and many other languages): they also indicate evaluation precedence for expressions. If you use parentheses in any other context but to enclose procedure call arguments, VB(A) will attempt to evaluate the expression in the parentheses to a resulting simple value.
Thus, in example 4, where parentheses are illegal for enclosing the arguments, VB(A) will instead attempt to evaluate the expression in the parentheses. Since (Value1, Value 2, Value3) is not an expression that can be evaluated, a syntax error ensues.
This also explains why calls with a variable passed ByRef act as if called ByVal if the argument is enclosed in parentheses. In the example above, where function p is called with ByRef parameter a, there is a big difference between these two calls to p:
6: p a
And
7: p(a)
As discussed above, 6 is the correct syntax: the call is alone on its line, so parentheses should not be used to enclose the arguments.
In 7, the argument is enclosed in parentheses anyway, prompting VB(A) to evaluate the enclosed expression to a simple value. Which of course is the very definition of passing ByVal. The parentheses ensure that instead of a pointer to a, the value of a is passed, and a is left unmodified.
This also explains why the parentheses rule doesn't always seem to hold sway. Clearest example is a MsgBox call:
8: MsgBox "Hello World!"
And
9: MsgBox ("Hello World!")
Are both correct, even though the parentheses rule dictates that 9 should be wrong. It is, of course, but all that happens is that VB(A) evaluates the expression in the parentheses. And the string literal evaluates to the exact same string literal, so that the actual call made is 8. In other words: calls to single-argument procedures with constant or string literal arguments have the identical result with or without parentheses. (This is why even my MsgBox calls are preceded by the Call keyword.)
Finally, this explains odd Type Mismatch errors and weird behavior when passing Object arguments. Let's say your application has a HighlightContent procedure that takes a TextBox as argument (and, you'll never guess, highlights it contents). You call this to select all text in the textbox. You can call this procedure in three syntactically correct ways:
10: HighlightContent txtName
11: HighlightContent (txtName)
12: Call HighlightContent(txtName)
Let's say your user has entered "John" in the textbox and your application calls HighlightContent. What will happen, which call will work?
10 and 12 are correct; the name John will be highlighted in the textbox. But 11 is syntactically correct, but will result in a compile or runtime error. Why? Because the parentheses are out of place. That will prompt VB(A) to attempt an evaluation of the expression in the parentheses. And the result of the evaluation of an object will most often be the value of its default property; .Text, in this case. So calling the procedure like 11 will not pass the TextBox object to the procedure, but a string value "John". Resulting in a Type Mismatch.
From Here:
Using the VBScript Call Statement to Call a Subroutine
The use of Call statement is optional when you wish to call a subroutine. The purpose of the Call statement when used with a Sub is to allow you to enclose the argument list in parentheses. However, if a subroutine does not pass any arguments, then you still should not use parentheses when calling a Sub using the Call statement.
Call MySubroutine
If a subroutine has arguments, you must use parentheses when using the Call statement. If there is more than one argument, you must separate the arguments with commas.
Call MySubroutine(intUsageFee, intTimeInHours, "DevGuru")
Calling the Function
There are two possible ways to call a function. You may either call the function directly, by name only, or you may call it by using the VBScript Call statement.
Calling a Function by Name
When calling a function directly by name and when there is no assignment to a returned value, all of the following are legal syntax:
MyFunction
MyFunction()
MyFunction intUsageFee, intTimeInHours, "DevGuru"
If you want a returned value, you can assign the function to a variable. Note that if there is one or more arguments, you must use the parentheses.
returnval = MyFunction
returnval = MyFunction()
returnval = MyFunction(intUsageFee, intTimeInHours, "DevGuru")
I just found some weird behavior calling a function with / without parentheses. Google took me here.
sub test()
dim a as double
a = 1#
p(a) 'this won't change a's value
Debug.Print a '1
p a ' this is expected behavior
Debug.Print a '2
Call p(a) 'this is also valid
Debug.Print a '3
end sub
Function p(a as Double) 'default is byref
a = a + 1
end function
My conclusion is that you have to use either Call or omitting the parentheses when calling a function with only one parameter, otherwise the parameter isn't passed by reference (it's still get called, as I checked already).
I just spent 10 minutes figuring out an "types incompatible" exception while calling a Sub which takes 1 argument via
CallMe(argument)
As it turns out, this is invalid, googling lead me here and finally
Call CallMe(argument)
or
CallMe argument
did the trick. So you must not use the brackets when calling a sub without the call-statement which only takes 1 argument.
When you use
Call MySub you should use parentheses around parameters, but if you omit Call, you don't need parentheses.
1 - By default, do not use parentheses when calling procedures or functions:
MsgBox "Hello World"
2 - If you are calling a function, and are interested in its result, then you must enclose its arguments with parentheses:
Dim s As String
Dim l As Long
s = "Hello World"
l = Len(s)
3 - If you want to use the call keyword with a procedure, then you must enclose the arguments with parentheses (e.g. when you want to assign the result in a variable or to use the function in an expression):
Call MsgBox("Hello World")
4 - If you want to force a ByRef argument (the default) to be passed ByVal, then enclose the ByRef argument with parentheses:
Sub Test
Dim text As String
text = "Hello World"
ChangeArgument((text))
MsgBox text
End Sub
Sub ChangeArgument(ByRef s As String)
s = "Changed"
End Sub
This displays "Hello World"
Well this was asked long ago but I just faced this problem and I found this question which I feel hasn't been fully answered yet. Hope I shed some light over this issue so that it serves for newcomers.
As I have seen previous answers mainly focus on the fact that whenever you use the "Call" statement you must enclose the arguments within parenthesis. Although this is true 1 it is definitely not the main source triggering this "strange" syntax errors.
The key point has been briefly noted by Cristopher. I'll just reference the documentation and further explain a little.
Ref Docs 2
So the main point is that the parenthesis determine whether you are interested in the return value of the function/sub/method/statement you are calling or not, that is, whether it must be returned to store it on a variable or not.
Having said that one may run into several problems
Calling with parenthesis a procedure that doesn't return a value 3.
Sub no_value_return(x as Integer)
Dim dummy as Integer
dummy = x
End Sub
'Error
no_value_return(1)
'No error
no_value_return 1
Calling with parenthesis a procedure that returns a value but not assigning it to a variable
Function value_return(ByVal x as Integer)
Dim value_return as Integer
value_return = x*2
End Function
'Error:
value_return(1)
'No error
Dim result as Integer
result = value_return(1)
Some additional examples
'Error - No value returned since no parenthesis were specified
Dim result as Integer
result = value_return 1
'No error - Special case
Dim result as Variant
result = value_return 1
'The reason for this is that variant is the only data type that accepts
'the special value "Empty"
'No error - You can perfectly ignore the returned value even if it exists
value_return 1
1 https://learn.microsoft.com/en-us/office/vba/language/concepts/getting-started/calling-sub-and-function-procedures
2 https://learn.microsoft.com/en-us/office/vba/language/concepts/getting-started/using-parentheses-in-code
3 Note this isn't aplicable for function procedures or built-in functions since those must always return a value
I use another logic to differ when to use brackets or not. If you function doesn't return a value (void type in C-liked languages), you don't need the parentheses. And it is always true for subs because returning value is the main difference between sub and function. Otherwise you have to use parentheses.
I am interested in creating a list / array of functions "G" consisting of many small functions "g". This essentially should correspond to a series of functions 'evolving' in time.
Each "g" takes-in two variables and returns the product of these variables with an outside global variable indexed at the same time-step.
Assume obs_mat (T x 1) is a pre-defined global array, and t corresponds to the time-steps
G = []
for t in range(T):
# tried declaring obs here too.
def g(current_state, observation_noise):
obs = obs_mat[t]
return current_state * observation_noise * obs
G.append(g)
Unfortunately when I test the resultant functions, they do not seem to pick up on the difference in the obs time-varying constant i.e. (Got G[0](100,100) same as G[5](100,100)). I tried playing around with the scope of obs but without much luck. Would anyone be able to help guide me in the right direction?
This is a common "gotcha" to referencing variables from an outer scope when in an inner function. The outer variable is looked up when the inner function is run, not when the inner function is defined (so all versions of the function see the variable's last value). For each function to see a different value, you either need to make sure they're looking in separate namespaces, or you need to bind the value to a default parameter of the inner function.
Here's an approach that uses an extra namespace:
def make_func(x):
def func(a, b):
return a*b*x
return func
list_of_funcs = [make_func(i) for i in range(10)]
Each inner function func has access to the x parameter in the enclosing make_func function. Since they're all created by separate calls to make_func, they each see separate namespaces with different x values.
Here's the other approach that uses a default argument (with functions created by a lambda expression):
list_of_funcs = [lambda a, b, x=i: a*b*x for i in range(10)]
In this version, the i variable from the list comprehension is bound to the default value of the x parameter in the lambda expression. This binding means that the functions wont care about the value of i changing later on. The downside to this solution is that any code that accidentally calls one of the functions with three arguments instead of two may work without an exception (perhaps with odd results).
The problem you are running into is one of scoping. Function bodies aren't evaluated until the fuction is actually called, so the functions you have there will use whatever is the current value of the variable within their scope at time of evaluation (which means they'll have the same t if you call them all after the for-loop has ended)
In order to see the value that you would like, you'd need to immediately call the function and save the result.
I'm not really sure why you're using an array of functions. Perhaps what you're trying to do is map a partial function across the time series, something like the following?
from functools import partial
def g(current_state, observation_noise, t):
obs = obs_mat[t]
return current_state * observation_noise * obs
g_maker = partial(g, current, observation)
results = list(map(g_maker, range(T)))
What's happening here is that partial creates a partially-applied function, which is merely waiting for its final value to be evaluated. That final value is dynamic (but the first two are fixed in this example), so mapping that partially-applied function over a range of values gets you answers for each value.
Honestly, this is a guess because it's hard to see what else you are trying to do with this data and it's hard to see what you're trying to achieve with the array of functions (and there are certainly other ways to do this).
The issue (assuming that your G.append call is mis-indented) is simply that the name t is mutated when you loop over the iterator returned by range(T). Since every function g you create stores returns the same name t, they wind up all returning the same value, T - 1. The fix is to de-reference the name (the simplest way to do this is by sending t into your function as a default value for an argument in g's argument list):
G = []
for t in range(T):
def g(current_state, observation_noise, t_kw=t):
obs = obs_mat[t_kw]
return current_state * observation_noise * obs
G.append(g)
This works because it creates another name that points at the value that t references during that iteration of the loop (you could still use t rather than t_kw and it would still just work because tg is bound to the value that tf is bound to - the value never changes, but tf is bound to another value on the next iteration, while tg still points at the "original" value.
I'm having trouble checking whether two strings are equal when one of them was passed through a splat argument. Because coffeescript uses strict comparisons, and because it makes a copy of the arguments when they go through a splat, I can't get the strings to compare properly without resorting to backticks. Is there a better way? Here's a minimal piece of code that demonstrates the problem:
check=(arg) ->
if arg == 'foo' then "'#{arg}'=='foo'" else "'#{arg}'!='foo'"
emit=(args...) ->
check(args)
console.log(emit('foo'))
console.log(check('foo'))
The output from this will be as follows:
> coffee mincase.coffee
'foo'!='foo'
'foo'=='foo'
EDIT:
mu is too short gave me the key, so the revised working code looks like this (everything is the same except emit)
emit=(args...)->
check.apply(null,args)
When you use a splat, the splat puts the splatted arguments into an array. For example:
f = (x...) -> console.log(x instanceof Array)
f(6)
will give you a true in the console. The fine manual isn't so fine in this case, it doesn't exactly spell it out, it assumes that you understand how JavaScript's arguments object works and leaves out the explicit splat puts your arguments into an array part.
So you end up passing an array to check and an array compared with a string using CoffeeScript's == (or JavaScript's ===) will never be true.
If you want emit to check the first argument, then you need to say so:
emit = (args...) -> check(args[0])
Demo: http://jsfiddle.net/ambiguous/TBndM/
I am using the PredicateBuilder class from http://www.albahari.com/nutshell/predicatebuilder.aspx
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
this extension method is chaining Predicates with the OR operator. on the page, the explanation says
We start by invoking the second expression with the first expression’s parameters. An Invoke expression calls another lambda expression using the given expressions as arguments. We can create the conditional expression from the body of the first expression and the invoked version of the second. The final step is to wrap this in a new lambda expression.
so if for example i have
Predicate<Book> p1 = b => b.Title.Contains("economy");
Predicate<Book> p2 = b=>b.PublicationYear>2001;
Predicate chain = p1.And(p2);
I didn't quite get the exlanation. can someone please explain how the code of the extension method above is working?
thanks
Let's rewrite the method body like this:
return Expression.Lambda<Func<T, bool>>(
Expression.OrElse(
expr1.Body,
Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>())
),
expr1.Parameters);
We should also keep in mind that expr1 is your existing expression that takes a T and returns a bool. Additionally, while the expression trees we are working with do not actually do anything (they represent something instead), I am going to use "do" henceforth because it makes for much easier reading. Technically for an expression tree to actually do something you have to compile it first and then invoke the resulting delegate.
Ok, so what do we have here? This is a lambda expression that takes whatever parameters expr1 takes (see last line) and whose body, as per the documentation, is
a BinaryExpression that represents a conditional OR operation that
evaluates the second operand only if the first operand evaluates to
false.
The first operand is expr1.Body, which means the resulting function (not actually a function, see note above) evaluates expr1. If the result is true it returns true on the spot. Otherwise, it invokes expr2 with the same parameters as those passed to expr1 (this means the single T parameter) and returns the result of that.
I was wondering. Are there languages that use only pass-by-reference as their eval strategy?
I don't know what an "eval strategy" is, but Perl subroutine calls are pass-by-reference only.
sub change {
$_[0] = 10;
}
$x = 5;
change($x);
print $x; # prints "10"
change(0); # raises "Modification of a read-only value attempted" error
VB (pre .net), VBA & VBS default to ByRef although it can be overriden when calling/defining the sub or function.
FORTRAN does; well, preceding such concepts as pass-by-reference, one should probably say that it uses pass-by-address; a FORTRAN function like:
INTEGER FUNCTION MULTIPLY_TWO_INTS(A, B)
INTEGER A, B
MULTIPLY_BY_TWO_INTS = A * B
RETURN
will have a C-style prototype of:
extern int MULTIPLY_TWO_INTS(int *A, int *B);
and you could call it via something like:
int result, a = 1, b = 100;
result = MULTIPLY_TWO_INTS(&a, &b);
Another example are languages that do not know function arguments as such but use stacks. An example would be Forth and its derivatives, where a function can change the variable space (stack) in whichever way it wants, modifying existing elements as well as adding/removing elements. "prototype comments" in Forth usually look something like
(argument list -- return value list)
and that means the function takes/processes a certain, not necessarily constant, number of arguments and returns, again, not necessarily a constant, number of elements. I.e. you can have a function that takes a number N as argument and returns N elements - preallocating an array, if you so like.
How about Brainfuck?