I can’t comment on the first issue since I don’t know what scan and dynamic_rnn is doing. I don’t see a problem with for loops, though. I would assume that nn.LSTM and nn.GRU also have internally a loop for processing the sequence. But that’s just my assumption.
Regarding sequences with variable lengths, you can do the same in PyTorch. Search for PackedSequence and pack_padded_sequence. There are also tool like the BucketIterator the creates batch with sequences of the same or almost the same lengths.
I guess you can get around by having a padding token in your embedding matrix. If you give the lengths to the RNN any tokens beyond that get ignored anyway. On the other hand, I can’t see any harm in having a dedicated padding token. The additional space and processing overhead is negligible.