Yes, plenty of other functional languages. I have literally never seen a line of Haskell before but I know ML, Scala and Python, so I can read the line pretty easily:
primes = sieve[2..] where sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]
[2..] is a list starting at 2; "where" is pretty clearly defining the function after using it. So sieve is a function; p:xs is a destructuring assignment or pattern or whatever you call it (I mean, xs clearly isn't a type, so I guess Haskell writes lists as 1 : 2 : 3 : Nil, where Scala or ML would use ::). (Which means this is a function that only works on a nonempty list, which seems a bit sneaky, but we can see that it's never going to be called for an empty one).
So sieve(p:xs) returns p:sieve(...), a fairly straightforward recursion. And the ... is fairly obviously a list comprehension I'd write in Python as "[x for x in xs if x % p != 0]".
Did I get it right?
The language certainly has an excess of symbols - I think the Python way of writing that list comprehension is much clearer - but it's certainly not incomprehensible; the "where" makes perfect sense, and the [] make a good visual distinction. The : form of lists is not the C way, but it's by no means unknown. The destructuring assignment might be unfamiliar, but once you've got that p:xs is a list there's only really one thing it could mean (and even in Python you can write (a, b) = something()). To a non-Haskeller it's kind of surprising that the code doesn't stack overflow from infinite recursion, but again, given that the code works, there's only one thing it could possibly mean.
This was much easier than the time when I tried to read some Clojure.
Edit: Just to be sure I got it, I rewrote the one-liner in Python. Had to use generators to get the laziness, and had to split it in two lines for the function:
def sieve(xs): p = next(xs); yield p; yield from sieve(x for x in xs if x % p != 0)
primes = sieve(itertools.count(2))
primes = sieve[2..] where sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]
[2..] is a list starting at 2; "where" is pretty clearly defining the function after using it. So sieve is a function; p:xs is a destructuring assignment or pattern or whatever you call it (I mean, xs clearly isn't a type, so I guess Haskell writes lists as 1 : 2 : 3 : Nil, where Scala or ML would use ::). (Which means this is a function that only works on a nonempty list, which seems a bit sneaky, but we can see that it's never going to be called for an empty one).
So sieve(p:xs) returns p:sieve(...), a fairly straightforward recursion. And the ... is fairly obviously a list comprehension I'd write in Python as "[x for x in xs if x % p != 0]".
Did I get it right?
The language certainly has an excess of symbols - I think the Python way of writing that list comprehension is much clearer - but it's certainly not incomprehensible; the "where" makes perfect sense, and the [] make a good visual distinction. The : form of lists is not the C way, but it's by no means unknown. The destructuring assignment might be unfamiliar, but once you've got that p:xs is a list there's only really one thing it could mean (and even in Python you can write (a, b) = something()). To a non-Haskeller it's kind of surprising that the code doesn't stack overflow from infinite recursion, but again, given that the code works, there's only one thing it could possibly mean.
This was much easier than the time when I tried to read some Clojure.
Edit: Just to be sure I got it, I rewrote the one-liner in Python. Had to use generators to get the laziness, and had to split it in two lines for the function:
Is that clearer than the Haskell? Maybe.