I know this is nitpicking, but you don't need to store the string to a variable or use a list for the positions in your second example. This one-liner suffices:
:Disp sub("AAAABBBBCCCCDDDD",4randInt(1,4)-3,4
That example is useful, though, because it shows the other way to approach putting the fortunes in a string. You can make all of the fortunes the same length by padding them with spaces, and then it's a constant length and starting position. Here is an example using different animal types:
// NOTE: Spacing goes 3 spaces, 2 spaces, and 1 space
:Disp sub("DOG FISH MOUSE RABBIT",6randInt(1,4)-5,6
While this approach works quite nice for a few fortunes, I'm not really sure how effective it would be with forty fortunes, and that's why I suggested using a list with all of the starting positions and fortune lengths. Then you can just access the appropriate list position like Socks was doing in his second example.