If you had a program back then full of gotos and an assembly language that didn't support structured blocks, your problem was just as bad.
At its core, FPR only requires higher-order functions to work. (And nearly every modern language supports them to some degree).
The things that Elm provides are additional niceties:
* A type system with parametry polymorphism (aka generics) helps you spot otherwise nasty runtime errors ("expected a function, got a signal").
* Abstract data types - The only way to create a signal is through the API. The only thing you can do with a signal is pass it around and feed it back into the API.
* Language purity - This one is probably the hardest sell for average languages, since every modern language (save Haskell) allows for unrestricted side-effects. However, as long as you don't bypass the API and update the UI directly, you don't actually NEED purity.