Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2: Added Swap(). #241

Open
wants to merge 1 commit into
base: alpha
Choose a base branch
from
Open

v2: Added Swap(). #241

wants to merge 1 commit into from

Conversation

jeeswg
Copy link
Contributor

@jeeswg jeeswg commented May 29, 2021

Description

Swap(&Var1, &Var2)

Swaps the contents of 2 variables.

Implementation

There were many possible avenues to consider with the Var class. I have found what appears to be a good solution, but would be happy with an alternative implementation.
(If any major changes are needed for the code, and a separate commit is created, that's fine, I don't need to be credited.)

VarSetStrCapacity uses &Var.
IsSet uses Var.
This PR uses &Var, but Var might be preferable, since it's convenient and simpler for newbies.
That said, it's used reasonably often, but not super often, so the convenience issue is less important.
I would be happy with either.

Alternatively, there could be a special syntax, a control flow statement. E.g. swap var1 var2.
That would encourage other programming languages that don't have ByRef variables, to take up the idea.

Rationale

Without a 'swap' function, you typically need 3 lines of code like this:

temp := var1
var1 := var2
var2 := temp

As simple as the long-form code is, it can be done incorrectly, introducing bugs. E.g. a variable renamed incorrectly.

In the long form, if you want to change a variable name, you have to rename it twice.

The use of the function name, Swap, makes the intention clear.
Versus 3 ordinary-looking, separate assignments, where, without a comment, it may not be clear that a swap is occurring.

One swap, or multiple swaps, can add unnecessary verbosity to otherwise succinct code. And for clarity, blank lines are needed above and below a swap 3-liner.

Swap is often useful in algorithms, e.g. when 2 limit values are specified, to set the first variable to be the lower limit.

Versus 3 separate assignments, this should avoid any unnecessary copying of data.

3 assignments to achieve a swap, is not great for debugging. To be sure that they successfully complete a swap, you have to painstakingly look through the code, or execute code to double-check the assignments.

I regularly see demands for 'swap' functionality (a function or special syntax) in other programming languages.
(Some languages don't have ByRef variables, so some form of special syntax would be needed.)
You often see ugly workarounds suggested for languages that lack 'swap' functionality.

Since no temporary variable is needed, you don't have to worry about adding/modifying local/global definitions.

Test code

;test Swap:

var1 := "a"
var2 := "b"

Swap(&var1, &var2)
MsgBox(var1 " " var2) ;b a

Swap(&var1, &var2)
MsgBox(var1 " " var2) ;a b

;==================================================

var1 := 123
var2 := 123.456
var3 := "abc"
var4 := ["value1"]
Swap(&var1, &var2)
Swap(&var2, &var3)
Swap(&var3, &var4)

MsgBox(var4) ;123
MsgBox(var1) ;123.456
MsgBox(var2) ;abc
MsgBox(var3[1]) ;value1

;==================================================

;it is not increasing the reference count:

ptr := ObjPtr(var3)
MsgBox(ObjAddRef(ptr)) ;2
Loop 20
	Swap(&var3, &var4)
MsgBox(ObjAddRef(ptr)) ;3

;==================================================

;can swap an unset var with a regular var:

;MsgBox(var1)
;MsgBox(var5)

Swap(&var1, &var5)

;MsgBox(var1)
MsgBox(var5) ;123.456

var5 := ""

;==================================================

MsgBox("done")

;==================================================

@jeeswg jeeswg changed the title v2: Swap v2: Added Swap(). May 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant