Does #discardableResult actually lead to compiler optimizations? - swift

I have an assignment operation that I want to also return the new value my object is assigned, but only optionally. So of course I would add the #discardableResult attribute. However, does this actually tell the compiler to ignore the return statement inside my function definition if it is not actually being passed anywhere? What optimization does this attribute actually do? All the documentation says is that it "suppresses the warning," although I only want to use it if it can be easily optimized.
Any help is appreciated!

Related

Why bother casting the return value since the type has been specified when calling the function?

I am learning Editor Script of Unity recently, and I come across a piece of code in Unity Manual like this:
EditorWindowTest window = (EditorWindowTest)EditorWindow.GetWindow(typeof(EditorWindowTest), true, "My Empty Window");
I don't know why bother casting the result with (EditorWindowTest) again since the type has been specified in the parameter field of GetWindow().
Thanks in advance :)
There are multiple overloads of the EditorWindow.GetWindow method.
The one used in your code snippet is one of the non-generic ones. It accepts a Type argument which it can use at runtime to create the right type of window. However, since it doesn't use generics, it's not possible to know the type of the window at compile time, so the method just returns an EditorWindow, as that's the best it can do.
You can hover over a method in your IDE to see the return type of any method for yourself.
When using one of the generic overloads of the GetWindow method, you don't need to do any manual casting, since the method already knows at compile time the exact type of the window and returns an instance of that type directly.
The generic variants should be used when possible, because it makes the code safer by removing the need for casting at runtime, which could cause exceptions.
If you closely look, GetWindow's return type is EditorWindow. Not the EditorWindowTest, so typecasting makes sense.
https://docs.unity3d.com/ScriptReference/EditorWindow.GetWindow.html

How to ignore a return value in Common Lisp

I'm working with some code which calls ADJUST-ARRAY. I am getting a warning message from the Lisp interpreter (CMUCL) that the return value of ADJUST-ARRAY should not be ignored.
In the code I am working on, ADJUST-ARRAY modifies its argument in place, if I am not mistaken. So it's not necessary to do anything with the return value. Is there a designated way to ignore a return value in Common Lisp? Of course, I could assign the return value to some variable, and then ignore the variable. But that feels clumsy.
I could also assign the return value to the ADJUST-ARRAY argument, something like:
(setq my-array (adjust-array my-array ...))
but that seems to suggest that I'm not sure if ADJUST-ARRAY will modify MY-ARRAY in place.
Any advice is welcome, thanks in advance.
You are correct. As the documentation states:
The result is an array of the same type and rank as array, that is
either the modified array, or a newly created array to which array
can be displaced, and that has the given new-dimensions.
If the result is a newly created array then of course the function would have had no effect on the argument.
Common Lisp almost always require you to use the returned value rather than old bindings in order to have portable code.
The specification of adjust-array is that the adjusted array is the one returned.
What you can expect of the argument array afterwards to be is a bit complicated and may differ between implementations in some cases.
Just use the one returned. You might use setf to modify or let to create a binding.

Is there a way to get warnings/errors when a return value of a specific type is unused?

Does Scala have some equivalent to Rust's #[must_use] annotation?
I have a type which always needs to have a method called on it after it is returned. There are several methods that return it, and ignoring the return value is always an error. (It makes calling the method that returned it entirely pointless.)
I can't use -Ywarn-value-discard because the codebase is full of other ignored returns which are fine. I only want a warning/error when certain types are discarded.
In 2.11: -Ywarn-unused Warn when local and private vals, vars, defs, and types are unused.
But that's not what exactly helps in your case.
scala does not warn about unused computation or value
--
For me, it's looks like design issue. Suppose you have init and execute methods.
execute can be invoked only after init... You should force user to invoke this init method before execute.
It can be lazily invoked in the execute or during class construction.
I do not really think about scenarios where you really need such warnings.

Can we say that using "pass by reference" is always better than "pass by value"?

In C# or php or other languages, there are 2 ways to pass a value to a function, pass it by value and pass it by referece.
Pass parameter by value make the value copied in the function, so this need a extra memory space although the memory space will be reclaimed after running outside the function.
But passing parameter by reference no need to copy a value, it's save the memory. From this perspective, can we say that using "pass by reference" is always better than "pass by value"?
Pass by reference and pass by value are semantically different and sometimes one is correct approach and sometimes the other one is. In many cases the task at hand already prescribes which approach is needed and in contexts where only one option is supported you often need to manually work around it (e.g., if you need a copy in Java you'll need to clone() the object).
In the context of generic functions the answer is rather the opposite way of your proposed preference: pass arguments of deduced type by value! The reason is that you can use something like std::ref() to obtain reference semantics but there is no way to get value semantics if the functions use reference semantics.
No.
There are tons of cases where you'd want to pass by value.
An example might be when you need both const Type& and Type&& overloads. Passing by value just handles both cases without having to duplicate any code:
void function(Object o) { do_something_with(std::move(o)); }
As opposed to:
void function(Object&& o) { do_something_with(std::move(o)); }
void function(const Object& o) { do_something_with(Object(o)); }
Of course there is much more to the subject, but since you're only asking for "is it always better?" I feel a single disproving example is enough. ;)
Edit: the question was originally tagged c++ hence my very specific answer.
Another, more language-agnostic example would be when you need to make a copy of your parameter because you don't want to modify the original object:
void function(int& val) { int v2 = val; modify(v2); use(v2); }
// vs
void function(int val) { modify(val); use(val); }
You get the idea...
Pass by reference requires copying a reference to the object. If that reference is comparable in cost to the object itself, then the benefit is illusory. Also, sometimes you need a copy of the object, and passing by value provides you one.
Also, there's a key error in the reasoning in the question. If passing by value, and there is no need to copy the value, nothing requires that the value actually be copied. Most languages have an "as-if" rule that states that the program only has to act as if the compiler did what you ask for. So if the copy can be avoided, the compiler is free to avoid it. If the copy can't be avoided, then you needed the copy.

scala - is it possible to force immutability on an object?

I mean if there's some declarative way to prevent an object from changing any of it's members.
In the following example
class student(var name:String)
val s = new student("John")
"s" has been declared as a val, so it will always point to the same student.
But is there some way to prevent s.name from being changed by just declaring it like immutable???
Or the only solution is to declare everything as val, and manually force immutability?
No, it's not possible to declare something immutable. You have to enforce immutability yourself, by not allowing anyone to change it, that is remove all ways of modifying the class.
Someone can still modify it using reflection, but that's another story.
Scala doesn't enforce that, so there is no way to know. There is, however, an interesting compiler-plugin project named pusca (I guess it stands for Pure-Scala). Pure is defined there as not mutating a non-local variable and being side-effect free (e.g. not printing to the console)—so that calling a pure method repeatedly will always yield the same result (what is called referentially transparent).
I haven't tried out that plug-in myself, so I can't say if it's any stable or usable already.
There is no way that Scala could do this generally.
Consider the following hypothetical example:
class Student(var name : String, var course : Course)
def stuff(course : Course) {
magically_pure_val s = new Student("Fredzilla", course)
someFunctionOfStudent(s)
genericHigherOrderFunction(s, someFunctionOfStudent)
course.someMethod()
}
The pitfalls for any attempt to actually implement that magically_pure_val keyword are:
someFunctionOfStudent takes an arbitrary student, and isn't implemented in this compilation unit. It was written/compiled knowing that Student consists of two mutable fields. How do we know it doesn't actually mutate them?
genericHigherOrderFunction is even worse; it's going to take our Student and a function of Student, but it's written polymorphically. Whether or not it actually mutates s depends on what its other arguments are; determining that at compile time with full generality requires solving the Halting Problem.
Let's assume we could get around that (maybe we could set some secret flags that mean exceptions get raised if the s object is actually mutated, though personally I wouldn't find that good enough). What about that course field? Does course.someMethod() mutate it? That method call isn't invoked from s directly.
Worse than that, we only know that we'll have passed in an instance of Course or some subclass of Course. So even if we are able to analyze a particular implementation of Course and Course.someMethod and conclude that this is safe, someone can always add a new subclass of Course whose implementation of someMethod mutates the Course.
There's simply no way for the compiler to check that a given object cannot be mutated. The pusca plugin mentioned by 0__ appears to detect purity the same way Mercury does; by ensuring that every method is known from its signature to be either pure or impure, and by raising a compiler error if the implementation of anything declared to be pure does anything that could cause impurity (unless the programmer promises that the method is pure anyway).[1]
This is quite a different from simply declaring a value to be completely (and deeply) immutable and expecting the compiler to notice if any of the code that could touch it could mutate it. It's also not a perfect inference, just a conservative one
[1]The pusca README claims that it can infer impurity of methods whose last expression is a call to an impure method. I'm not quite sure how it can do this, as checking if that last expression is an impure call requires checking if it's calling a not-declared-impure method that should be declared impure by this rule, and the implementation might not be available to the compiler at that point (and indeed could be changed later even if it is). But all I've done is look at the README and think about it for a few minutes, so I might be missing something.