No. It's a very meaningful distinction, actually.
Compare:
Ruby:
will_print = puts "hello world" # it already print to the screen! and will_print does not have any meaningful value -- indeed it's nil
Haskell (demonstrated on the repl, which runs inside the IO monad):
let willPrint = putStrLn "hello world" -- nothing gets printed!
willPrint -- now the string gets printed (only because the repl is inside the IO monad which promises to execute action values)
Haskell (not in the repl):
willPrint = putStrLn "hello world" -- nothing gets printed!
willPrint -- this returns the same that 'putStrLn "hello world"' returns - an action value that, when run inside the IO monad, will execute its actions - so this still doesn't print anything, and we can pass willPrint around without side-effects, and compose values with willPrint
main = willPrint -- now the compiler will make good on its promise to execute any action value that is named 'main', and "hello world" will be printed to the screen.
The point of this is that you cannot print inside the Haskell language (nor do any other side-effect) - when you try to print you get this "action value" thing that you as a programmer cannot execute. Only the compiler can. So you can pass Ruby's equivalent of "puts 'hello world'" around, which you can't in Ruby.
So the distinction is quite clear.
> Programs written in C, Python, Ruby, ML, R, and Brainfuck only have side effects when you execute them.
They clearly don't. That's why when I write in Ruby:
puts "hello world"
Then the next line of code will be executed in a world where 'hello world' has already been printed to the screen.
Likewise, when in Ruby I write:
a = 5
a += 1
Then the next line of code will be executed in a world where a is 6.
So every line of code you write depends on the side-effects that came before it. Therefore, Ruby and most other languages have side-effects before code is executed. This is not the case in Haskell. Hence, no side-effects.