Hacker News new | past | comments | ask | show | jobs | submit login

> Haskell has both do-notation and list comprehension.

Right, and do-notation is the one everyone uses, because it's better. Python picked the wrong one.

> Comprehension in both Python and Haskell (for both lists and other structures) use the same order in both language, as far as I remember.

It may be the same order as Haskell but it's a terrible confusing order. In particular if you want to go from a nested list comprehension to a flat one (or vice versa) then you have to completely rearrange the order it's written in, whereas if you go from nested do-blocks to flat do-blocks then it all makes sense.




I see what you mean, but I don't find the order that confusing in neither Haskell or Python.

However, I can imagine a feature that we could add to Python to fix this: make it possible for statements to have a value. Perhaps something like this:

    my_generator = \
      for i in "abc":
        for b in range(3):
          print("foo")
          yield (i, b)
or perhaps have the last statement in block be its value (just like Rust or Ruby or Haskell do with the last statement in a block), and make the value of a for-loop be a generator of the individual values:

    my_list = list(
      for i in "abc":
        for b in range(3):
          (i, b))
Though there's a bit of confusion here whether the latter examples should be a flat structure or a nested one. You could probably use a similiar mechanism as the existing 'yield from' to explicitly ask for the flat version, and otherwise get the nested one:

    my_list = list(
      for i in "abc":
        yield from for b in range(3):
          (i, b))
Making Python statements have values looks to me like the more generally useful change than tweaking comprehensions. You'd probably not need comprehension at all in that case. Especially since you can already write loop header and body on a single line like

    for i in range(10): print(i)
if they are short enough.


  for i in range(10): print(i)
But what would that return? [None] * 10?

The limited whitespace-based syntax limits the potential for fun inline statement things, but it also completely dodges the question of what any particular statement should evaluate to when used as an expression.


> But what would that return? [None] * 10?

Yes, I guess something like that. That was just meant as an example of how existing Python allows you to write loops on one line. It's not a good example for a meaningful comprehension in our alternative made-up Python dialect.

> The limited whitespace-based syntax limits the potential for fun inline statement things, [...]

Python already mostly allows you to use parens to override the indentation. They would just need to generalise that a bit. Btw, Haskell already does that:

Officially, Haskell has a syntax with curly braces and semicolons; and they define the indentation based syntax as syntactic sugar that desugars to ; and {}. But almost everyone uses indentation based syntax. The exception are perhaps code generators and when posting on a website that messes with indentation.

(And, because it's Haskell, the {}; syntax is just another layer of syntactic sugar for 'weird-operator'-based based syntax like >>=.)


When I was starting in Python years ago I had to turn my brain inside out to learn how to write list comprehensions. Sometimes I wonder what it's like to be a normal person with a normal non-programmer brain, having forgotten it entirely these last many years.


But Python doesn't have any concept of a monad, so what would do-notation even be in Python? And who is the "everyone" using do-notation? I don't see any analogous syntax in Lua, Javascript, Ruby, or Perl.

In Python there is a nice tower of abstractions for iteration, but nothing more general than that, so it makes perfect sense IMO to use the syntax that directly evokes iteration.

The existing syntax is meant to mirror the syntax of a nested for loop. I agree that maybe it's confusing, but if you want to go from a multi-for comprehension to an actual nested for loop, then you don't have to invert the order.


> But Python doesn't have any concept of a monad, so what would do-notation even be in Python?

It could work on the same things that Python's current list comprehensions work on. I'm just suggesting a different syntax. Comprehensions in Haskell originally worked for all monads too.

> And who is the "everyone" using do-notation? I don't see any analogous syntax in Lua, Javascript, Ruby, or Perl.

I meant that within Haskell, everyone uses do notation rather than comprehensions.

> The existing syntax is meant to mirror the syntax of a nested for loop. I agree that maybe it's confusing, but if you want to go from a multi-for comprehension to an actual nested for loop, then you don't have to invert the order.

You have to invert half of it, which I find more confusing than having to completely invert it. do-notation style syntax (e.g. Scala-style for/yield) would keep the order completely aligned.


> Comprehensions in Haskell originally worked for all monads too.

And that behaviour is still accessible via a compiler extension.


Idris 2 still has both "monad comprehensions" and an applicative equivalent called "idiom brackets".

https://idris2.readthedocs.io/en/latest/tutorial/interfaces....

https://idris2.readthedocs.io/en/latest/tutorial/interfaces....





Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: