After Effects: Linear Expression - going from value 1 to another value and then back to value 1
Is there any reason why you're using this approach? There are far easier ways to do it (see below). 

But anyway the problem is that the second last and last line both return values, but an expression can only return one set of values, and so it only returns the last one. I think this points to a misunderstanding of how expressions work. An expression is calculated every frame*; it has no memory of what happened previously or what will happen later. So your expression has to return one result for any particular point in time, and the result is calculated from the value it returns at that time.

You need some flow control there. Use an if/else statement to replace the last two lines:

if (time &lt; mid1){
    [linear(time, start1, mid1, 640, effect("End Position")("Point")[0]), linear(time, start1, mid1, 360, effect("End Position")("Point")[1])];
}else{
    [linear(time, mid1, end1, effect("End Position")("Point")[0], 640), linear(time, mid1, end1, effect("End Position")("Point")[1], 360)];
}


But you can make your life a lot easier. Why not have a slider effect that has a 0-100 range that defines what percentage of the distance along the path the object should be at. Then you just keyframe it to ramp from 0-100 and back again. The whole expression would just be:

rampCtrl=effect("the Effect That Controls How Far Along It is")("slider");
linear(rampCtrl, 0, 100, [640,360], effect("End Position")("Point"))


Note that you don't have to split it into two parts, the linear() function can deal with vectors as the value1 and value2 inputs.

*(you can think of expressions as being calculated every frame, but they are actually calcualted every time the comp is rendered. If you have motion blur on, the frame is composed of numerous time slices at sub-frame points in time, blended together, and the expression is calculated for each of those time slices. Generally you can ignore this, but it does impact rendering speed if your calcualtion is very time consuming, and it can cause weirdness if your expression returns unexpected results between frames, e.g. when looping back to an original value between two frames)