Why does Go slice `append()` not take a reference? - go

Go Lang's slice append() might allocate a new backing array to make room for the new item. Thus, after a call z = append(x,y), if z's front most elements are modified, x is essentially unspecified -- it might or might not have the same backing array as z, and z could mutate its backing array with z[0] = foo, which thus might or might not modify x's backing array.
So, why let this ugliness surface? Instead making it a program bug to assign the result of append to anything but its first argument, why not have append take a *[]T instead, so no reassignment is needed and no undefined variable is left dangling.
This wouldn't solve every case, because a = x; append(&x,y) would still make a undefined, but a partial improvement seems better than none.

It's not quite true that in your first example (z = append(x, y)), x is undefined. Instead, x still points to the original contents of x, while z points to those contents and then some. As you mention, there are two possibilities:
cap(x) > len(x), in which case append simply returns x[:len(x)+1] (ie, extends the length of the returned slice to contain one extra element)
cap(x) == len(x), in which case append creates another array by copying over the contents of x and then appends y as the len(x)-th element.
In either of these cases, x is left largely unchanged in the sense that all of the elements of x are still there. You obviously have to be careful now that you potentially have two references to the same underlying data, but the point stands that keeping x around can be useful.
That said, I agree that maybe having append take a pointer might be simpler, and maybe this possible use case that I've just described isn't common enough to warrant the potentially confusing, mildly more verbose semantics.

Related

Mutable data types that use stack allocation

Based on my earlier question, I understand the benefit of using stack allocation. Suppose I have an array of arrays. For example, A is a list of matrices and each element A[i] is a 1x3 matrix. The length of A and the dimension of A[i] are known at run time (given by the user). Each A[i] is a matrix of Float64 and this is also known at run time. However, through out the program, I will be modifying the values of A[i] element by element. What data structure can also allow me to use stack allocation? I tried StaticArrays but it doesn't allow me to modify a static array.
StaticArrays defines MArray (MVector, MMatrix) types that are fixed-size and mutable. If you use these there's a higher chance of the compiler determining that they can be stack-allocated, but it's not guaranteed. Moreover, since the pattern you're using is that you're passing the mutable state vector into a function which presumably modifies it, it's not going to be valid or helpful to stack allocate that anyway. If you're going to allocate state once and modify it throughout the program, it doesn't really matter if it is heap or stack allocated—stack allocation is only a big win for objects that are allocated, used locally and then don't escape the local scope, so they can be “freed” simply by popping the stack.
From the code snippet you showed in the linked question, the state vector is allocated in the outer function, test_for_loop, which shouldn't be a big deal since it's done once at the beginning of execution. Using a variably sized state vector to index into an array with a splat (...) might be an issue, however, and that's done in test_function. Using something with fixed size like MVector might be better for that. It might, however, be better still, to use a state tuple and return a new rather than mutated state tuple at the end. The compiler is very good at turning that kind of thing into very efficient code because of immutability.
Note that by convention test_function should be called test_function! since it modifies its M argument and even more so if it modifies the state vector.
I would also note that this isn't a great question/answer pair since it's not standalone at all and really just a continuation of your other question. StackOverflow isn't very good for this kind of iterative question/discussion interaction, I'm afraid.

When to rename variables in lambda calculus?

I understand why renaming variables to avoid capture is important but, in the following example, I don't understand why it doesn't occur.
(λf.λx.f(fx))(λf.λx.fx)
apparently reduces to
λx.(λf.λx.fx)((λf.λx.fx)x)
but shouldn't x be renamed in either (λf.λx.f(fx)) or (λf.λx.f(fx))? Don't they refer to different xs?
Capture avoidance is to avoid capturing free variables. "Capturing" bound variables doesn't hurt that much: In
λx.(λf.λx.fx)((λf.λx.fx)x)
the two uses of x are indeed different variables, but this is already encoded in the term: In general, a new abstraction in a subterm will "overwrite" the binding of further outmost abstractions. This is simply due to the way the evaluation of lambda terms works: If there is a new abstraction over the same variable, then the old abstraction further out will ultimately lose its effect in the subterm with the new abstraction, and the variables bound by the inner abstraction will effectively be different variables than the ones only bound by the outer abstraction.
You can try this out: If you apply λx.(λf.λx.fx)((λf.λx.fx)x) to some term N, then according to the definition of beta reduction, this term will reduce to (λf.λx.fx)((λf.λx.fx)x)[N/x], i.e. the term obtained by substituting every free (!) occurence of x in (λf.λx.fx)((λf.λx.fx)x) by N (substitution only operates on free variables by definition). The only free occurrence of x in that term is the very last one; the other two xes in the two subterms (λf.λx.fx) are bound by their respective λx's. So the only x that will be substituted by N is the last one, hence (λx.(λf.λx.fx)((λf.λx.fx)x))N will reduce to (λf.λx.fx)((λf.λx.fx)N) - the x's bound in the subterms (λf.λx.fx) remain unchanged.
So the x's bound by the inner abstraction and the x at the end of the term are indeed different variables belonging to different abstractions. Therefore it is unproblematic not to rename them during the application.
That being said, it can sometimes be useful to do such renamings for easier readability. The resulting term will be alpha-congruent to the one obtained by directly substituting without renaming.

GNU Simulated Annealing

I'm working from the template program given here:
https://www.gnu.org/software/gsl/manual/html_node/Trivial-example.html
The program as they give it compiles and runs perfectly, which is nice. What I would like to do is generalise this method to find the minimum of a function with an arbitrary number of parameters.
Some cursory reading suggests that the metric function (M1) is only used in certain diagnostic and printing situations and so can more or less be ignored. All that remains is then to define E1 and S1 appropriately. Unfortunately my knowledge of using pointers and void is incomplete, so I'm stuck trying to upgrade the configuration 'xp' to be an array of parameters, rather than a single double.
In my naivete tried moving from
double x = *((double *) xp);
to
double x = (*((double *) xp))[0];
where appropriate, but obviously that didn't work. I'm sure I'm missing something stupid, so any hints would be nice! I will obviously be defining my own E1 output function which will take these N parameters and return a number.
The underlying algorithm, gsl_siman_solve() from the link provided, is generalized to work with any data type. This is why the ubiquitous xp parameter is always being cast to a double pointer before use. It should be straightforward to use any struct or array or array of arrays instead of simply doubles provided all the callbacks are coded properly.
The problem is that gsl_siman_solve() only seems to support a scalar double step size, initial guess, and 'uniform' value (from gsl_rng_uniform()), so you would need to map scalar double values into what are naturally multidimensional quantities. This can be done, but it is messy and not very flexible. In your case, the mapping would be done in S1().
This is akin to mapping the digits of a decimal number into a multidimensional space: the ones digit represents the X axis, the tens digit represents the Y axis, and the hundreds digit represents the Z axis, for example. By incrementing an integer, one can walk the entire 3D space from (0, 0, 0) to (9, 9, 9). You don't have to use integers and powers of 10, and the components don't even have to have the same range, but there is an inherent limit in the range of each component of the packed value. You would actually do this in reverse: taking a scalar double and unpacking it into multiple quantities.
Lastly, your code double x = (*((double *) xp))[0]; won't work because you are attempting to dereference a double as an array, not a pointer to a double, which would be OK. In other words, it's that first * that is the problem.

Why doesn't the following function work for recursive appending to a list in swi prolog?

I have a list L and I need to split each element into a separate list and again append them together. This is the code I made for the same.
split([],[]).
split([H|T],Ls):-split(T,Ls),splist(H,[]).
make(Val,[H1|List],[H1|Res]):- make(Val,List,Res). make(Val, List,[Val|List]).
splist(H,L2):- make(Sum,[],L1),append(L1,L2,NewL).
When I use this code, each element of L is passed recursively from split() to splist() and made into a list L1 with single element by make(). I need append to keep concatenating L1 and L2. But it does not so so
For example, I have L=[1,2,3]. Now I need the following process to be done.
H=1, L1=[1] and L2=[1]. Next H=2, L1=[2] and L2=[1,2]. Next H=3, L1=[3] and L2=[1,2,3].
I need the output as mentioned above, but this is what my code does.
H=1, L1=[1], and L2= [1]. Next H=2, L1=[2] and L2=[2]. Next H=3, L1=[3] and L2=[3].
I can't make any sense out of your code. make definition is incomplete. As is, it does nothing and then fails.
Your split is equivalent to split(X,[]):- reverse(X,R), maplist(spl([]),R). with spl(B,A):-splist(A,B)., i.e. it tries splist(H,[]) for each element H of the input list X, backwards, to see whether it fails or not - that's its only outcome, as the arguments are fixed - H and [].
naming your predicates split and splist is a very bad idea - we humans are wired to distinguish words from their start, and the only different letter in these names is hidden way far near the end. IOW the two names are very similar, and it is very easy to misread and mistype them.
lastly, for splist(H,L2):- make(Sum,[],L1),append(L1,L2,NewL)., since make cn only fail, so will splist. But even if make were to produce something in L1 out of thin air - Sum starts out uninstantiated mind you - what does it say about L2? That it can be appended to the list L1? Any list can be appended to any other, saying that is saying nothing.
?? :)

insert element in a list and return the same list updated

Hi i'm trying to insert an element in a list but it is very important from my program that the result is stored in the original list and not in a new one.
Any code that i have written or found on the internet only succeeds if you create a new list in which the end result is kept.
So my question is can anyone tell me how to define a function: insert(X,L) where X is an element and L is a list?
No, Prolog just doesn't work that way. There is no such thing as "modifying" a value. A variable can be unified with a specific value, but if it was already [1,3], it won't ever be [1,2,3] later.
As aschepler says, you cannot add or make any change to a proper list, i.e. a list in which every element is already bound. The only "modifying" we can do is unifying one expression with another.
However there is a concept of a partial list to which additional elements can be "added" at the end. This is typically known as a difference list, although that nomenclature may not be immediately understandable.
Suppose we start, not with an empty list, but with a free variable X. One might however think of subtracting X from X and getting "nothing". That is, an empty difference list is represented by X - X. The minus "-" here is a purely formal operator; no evaluation of the difference is intended. It's just a convenient syntax as you see from how difference lists can be used to accomplish what you (probably) want to do.
We can add an element to a difference list as follows:
insertDL(M,X-Y,X-Z) :- Y = [M|Z].
Here M is the new element we want to add, X-Y is the "old" difference list, and X-Z is the "new" difference (to which M has been added, by unifying the previously free variable Y with the partial list [M|Z], so that Z becomes the "open" tail of partial list X).
When we are finally done inserting things into our difference list, we can turn X into a proper list by setting the "free tail" at that point to the empty list [ ]. In this sense X is the "same" variable as when we first began, just unified by incremental steps from free variable to proper list.
This is a very powerful technique in Prolog programming, and it takes some practice to feel comfortable using it. Some links to further discussion on the Web:
[From Prolog lists to difference lists]
http://www.irisa.fr/prive/ridoux/ICLP91/node8.html
[Implementing difference lists in Prolog]
http://www.cl.cam.ac.uk/~jpw48/difflists.pdf
[Lecture Notes: Difference Lists]
http://www.cs.cmu.edu/~fp/courses/lp/lectures/11-diff.pdf
Some prologs provide the setarg/3 predicate in order to modify terms in place.
In order to use it over lists, you only need to consider that they are just a nice representation of chains of compound terms with functor '.'/2
In any case, when you need to use setarg/3 in Prolog, it probably means you are doing something wrong.

Resources