Giving the following function in Pascal where GetChar is another function. How is GetChar executed after the function returns with the := operator?
function GetNum: char;
begin
GetNum := Look;
GetChar;
end;
The assignment in Pascal doesn't return, it is just an assignment. So GetChar will be executed.
Related
I am trying to manipulate a sub-array of an existing array. Can Codesys do this? I guess this is more of a syntax question.
In Python, there is slice() is there a Codesys equivalent?
Here's some pseudocode of what I am trying to do
VAR
Array1: ARRAY [1..3, 1..3] OF BOOL;
Statement: BOOL;
END_VAR
IF
Statement := TRUE
THEN
Array1[1,1..3] :=TRUE;
END_IF
[1,1..3] or [1,1:3] are not valid syntax. What is the appropriate way to access multiple cells?
You cannot set single value to a range of array elements. Syntax [1,1..3] or [1,1:3] will not work. You can only access one element at a time.
Array1[1,1] := TRUE;
Array1[1,2] := TRUE;
Array1[1,3] := TRUE;
Or
Array1[1,1] := Array1[1,2] := Array1[1,3] := Statement;
In A Tour of Go is written:
The deferred call's arguments are evaluated immediately, but the
function call is not executed until the surrounding function returns.
I have difficulty in understanding the first part of the quote. What is called immediately?
func def(s string) func() {
fmt.Println("tier up")
fmt.Println(s)
return func(){ fmt.Println("clean up") }
}
func main() {
defer def("defered line")()
fmt.Println("main")
}
//Output:
//tier up
//defered line
//main
//clean up
https://play.golang.org/p/Av3mAEXxA4R
What is deferred here and what is evaluated immediately?
To learn how defer and evaluations work, first let's look at the Spec: defer statements:
Each time a "defer" statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function is not invoked.
Both the function value (whose call is deferred) and its parameters are evaluated. But the deferred function is not yet called.
Let's iterate toward your example with small steps:
defer f("a")
In this case the function value is evaluated (which will be f), and the parameters are evaluated, which is a constant, so that's gonna be "a".
Next step:
defer f(g("a"))
In this case the function value is evaluated (which will be f), and the parameters are evaluated, which means g will be called with "a" (because g's return value is the param to f).
Next step:
defer f()()
This is valid if the f function returns a function. The function value will be evaluated (which means f will be called!) but its return value will not be called, that is what will be deferred.
defer f(g())()
In this case the deferred function is the return value of f, so to evaluate the deferred function value, f must be called, and to do that g must be called prior. The return value of f will be deferred (not called).
Back to your example:
defer def("defered line")()
The function value is evaluated, which is the return value of def, so def is called. The return value of def will be deferred. Its parameters are evaluated, but actually it has no parameters.
So logically this is what happens:
The deferred function value is evaluated, which requires that:
def function must be called, which requires that:
Params to def are evaluated, it's a constant: "defered line"
Parameters to the deferred function are evaluated; since there are no params to it, this step is done.
This is what happens sequentially if we lay out the above structure:
Param to def is evaluated: it's a constant "defered line"
def is called which prints tier up and its argument: defered line
The return value of def is not called, that is what's deferred.
Function main prints: main
Function main returns, so deferred functions are called now. The deferred function prints clean up
The deferred call's arguments are evaluated immediately, but the
function call is not executed until the surrounding function returns.
Above sentence means the deferred function arguments are evaluated at the line where they are deferred but the function will run after the surrounding function which is main returns.
A defer statement pushes a function call onto a list. The list of
saved calls is executed after the surrounding function returns. Defer
is commonly used to simplify functions that perform various clean-up
actions.
Deferred function calls are executed in Last In First Out order after the surrounding function returns.
Deferred functions may read and assign to the returning function's named return values.
The above line clearly states that it will return the value to the main function.
For eg:-
func c() (i int) {
defer func() { i++ }()
return 1
}
Above function will return 2 value rather than 1. That's why this line
return func(){ fmt.Println("clean up") }
will be called in the last.
For more information on defer. Please read golang blog for defer
It will be more clear if you change the argument you're passing to def(string) from a string literal (evaluated at compile time) to something more interesting, say:
func bar(s sting) string {
return s + " bar "
}
func main() {
defer def(bar(os.Args[1]) + "defered line")()
fmt.Println("main")
}
When the defer def(bar(os.Args[1]) + "defered line")() statement
is executed, the argument to def will be fully evaluated,
and this means calling bar passing it the first command-line
argument supplied by the user when running your program,
taking whatever bar returned and appending
a string literal to it.
The resulting string is then saved, and will be passed to def
when it will run.
In
defer def("defered line")()
def("defered line") and () are deferred call's arguments evaluated immediately.
def("defered line") evaluates to func(){ fmt.Println("clean up") } with side effects.
As it says in the title.
I'm writing a program which asks the user to input a surname surname then a first name and finally an address.
When this is done it prints out a table of the results and then organises then alphabetically based first on surname, then first name and finally address.
All this is done. I just have to make it that the table always prints out with first letters uppercase and the rest lowercase, ie:
input: jOHN SMith
output: John Smith
How can I do this in Pascal?
Here is the code I've written for this part so far:
writeln();
write(UpCaseFirstChar(arrSurnames[count]):15);
write(UpCaseFirstChar(arrFirstNames[count]):15);
write(UpCaseFirstChar(arrAddress[count]):30);
writeln();
I have a function for uppercasing the first letter, how can I change it to lowercase the rest?
EDIT: Here is the uppercase function:
function UpCaseFirstChar(const S: string): string;
begin
Result := S;
if Length(Result) > 0 then
Result[1] := UpCase(Result[1]);
end;
EDIT 2: I think I figured it out. Here is the new code for the UpCase/LowerCase function in case anyone is interested:
function UpCaseFirstChar(const S: string): string;
var
i: integer;
begin
Result := S;
if Length(Result) > 0 then
Result[1] := UpCase(Result[1]);
for i := 2 to Length(Result) do
begin
Result[i] := LowerCase(Result[i]);
end;
end;
Your update is more verbose than it needs to be. If you read the documentation carefully, the function LowerCase applies to a string. So you could write:
function UpCaseFirstChar(const S: string): string;
begin
if Length(S) = 0 then
Result := S
else begin
Result := LowerCase(S);
Result[1] := UpCase(Result[1]);
end;
end;
What happens when the assign operator := gets overloaded in Object Pascal? I mainly mean what gets evaluated first and more importantly how (if possible) can I change this order. Here is an example that bugs me:
I declare TMyClass thusly:
TMyClass = class
private
FSomeString: string;
class var FInstanceList: TList;
public
function isValid: boolean;
property SomeString: String write setSomeString;
end;
the isValid function checks MyObject for nil and dangling pointers.
Now lets assume I want to overload the := operator to assign a string to TMyClass. I also want to check if the object I'm assigning this string to is a valid object and if not create a new one, so:
operator :=(const anewString: string): TMyClass;
begin
if not(result.isValid) then
result:= TMyObject.Create;
result.SomeString:= aNewString;
end;
In short I was hoping that the result would automatically hold the pointer to the object I'm assigning to. But tests with the following:
procedure TForm1.TestButtonClick(Sender: TObject);
var
TestObject: TMyObject;
begin
TestObject:= TMyObject.Create;
TestObject:= 'SomeString';
TestObject.Free;
end;
led me to believe that instead an intermediate value for result is assigned first and the actual assignment to TestObject happens after the code in := executes.
Everything I know about coding is self taught but this example shows that I clearly missed some basic concept somewhere.
I understand that there are easier ways to do this than by overloading a := operator but out of scientific curiosity is there ANY way to make this code work? (No matter how complicated.)
It's not possible to do what you want with operator overloads. You must use a method.
The problem is that the := operator does not give you the access to the left hand side (LHS) argument (here it's the Self, a pointer to the current instance) but only to the right hand side argument.
Currently in you example if not(result.isValid) then is dangereous because the result at the beginning of the function is undefined (it can have any value, it can be either nil or not and when not nil, calling isValid will lead to some possible violation access. It does not represent the LHS at all.
Using a regular method you would have an access to the Self and you could call isValid.
I do not have Lazarus to check, but it is possible in Delphi in the following way. We give access to an instance of the class indirectly via TValue.
Here is a sample class:
type
TMyClass = class(TComponent)
private
FSomeString: string;
published
property SomeString: string read FSomeString write FSomeString;
end;
And we do the following in the container class (for example, TForm1).
TForm1 = class(TForm)
private
FMyClass: TMyClass;
function GetMyTypeString: TValue;
procedure SetMyTypeString(const Value: TValue);
public
property MyClass: TValue read GetMyTypeString write SetMyTypeString;
end;
...
function TForm1.GetMyTypeString: TValue;
begin
Result := FMyClass;
end;
procedure TForm1.SetMyTypeString(const Value: TValue);
begin
if Value.Kind in [TTypeKind.tkChar, TTypeKind.tkUString,
TTypeKind.tkString, TTypeKind.tkWChar, TTypeKind.tkWString]
then
begin
if not Assigned(FMyClass) then
FMyClass := TMyClass.Create(self);
FMyClass.SomeString := Value.AsString;
end else
if Value.Kind = TTypeKind.tkClass then
FMyClass := Value.AsType<TMyClass>;
end;
In this case both button clicks will work properly. In other words, it simulates := overloading:
procedure TForm1.Button1Click(Sender: TObject);
begin
MyClass := 'asd';
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
MyClass := TMyClass.Create(self);
end;
And here is how to get access to TMyClass instance:
procedure TForm1.Button3Click(Sender: TObject);
begin
if Assigned(TMyClass(MyClass.AsObject)) then
ShowMessage(TMyClass(MyClass.AsObject).SomeString)
else
ShowMessage('nil');
end;
I am having trouble transferring a variable into an anonymous function. Is there a solution?
import "github.com/lxn/walk"
***
var openAction [12]*walk.Action
for i := 0; i < 12; i++ {
openBmp, err := walk.NewBitmapFromFile(_films[i][0])
if err != nil {
log.Printf("Open bitmap for buildBody() :%v\n", err)
}
openAction[i] = walk.NewAction()
openAction[i].SetImage(openBmp)
openAction[i].SetText(_films[i][2])
openAction[i].Triggered().Attach( func(){
exec(i)
})
mw.ToolBar().Actions().Add(openAction[i])
}
exec(i) where i always = 11
for i := 0; i < 12; i++ {
i := i
...
Crazy as it looks, this is something you will see in Go code. It results from the way closures work and the way variables are scoped. Your anonymous function is a closure that captures i. Specifically, it is capturing a variable called i, not the current value of i, and it captures whatever i is in scope. In your original code this is the loop variable, which is the same variable for each iteration of the loop. All of your closures captured the same variable. The addition of i := i declares a new variable on each iteration. Now each closure will capture this new variable, and on each iteration it will be a different variable.
In a little more detail, the scope of the loop variable i is the for statement. This includes the loop block, but since the declaration of the loop variable i is outside of the block, declaring a new variable with the same name inside the block is legal and creates a new variable at that point in the block. The loop variable is then shadowed. Often a variable declared like this goes on the stack, but in this case compiler escape analysis sees that your closure is still referring to this block variable when it goes out of scope at the end of the block, and so the variable is placed on the heap. On each iteration, the block is reentered and a new variable i is placed on the heap.
I think that this will get you what you want:
openAction[i].Triggered().Attach(func(x int) func() {
return func() { exec(x) }
}(i))
The trick is to have your anonymous function return an anonymous function, and each created function will enclose each of the values of i.
You are encountering a quirk of go's for loops. The i variable in the loop is not a new variable for each iteration. because of this all of your closures are closing over the same variable whose value is changing underneath them. When your code runs after the loop all of the functions see the value 11 for the i they closed over.
The solution is to pass the i into a function which then returns another function that closes over the functions arg. This is why Adam Crosslands solution works.