Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

F#:

    List.init 4 (fun _ -> [])

    [for _ in 1..4 -> []]
Or any sane language that uses immutable values by default like Elixir, Erlang, Clojure, Racket, Scheme, OCaml, etc.

> Actually, if you really want to have re-evaluting (sub)expressions, then Python does give you an option: comprehensions.

That's the complaint, that [[]]*4 is not shorthand for list comprehensions and that it's something entirely different. This is common in Python where two things you'd expect to be the same are indeed different in subtle ways.

List comprehensions in Python are closer to sane, but they still have unexpected behavior because of the way scoping works in Python.



> That's the complaint, that [[]]4 is not shorthand for list comprehensions

There are lots of reasons you would want items in a list repeated rather than having, essentially, the result of separate executions of the same constructor -- [] is just shorthand for list() -- so its good that [x()]4 is not shorthand for [x() for _ in range(4)]. Especially since that would mean it would have to be special-case sytax for list construction, and not a list operator that you could use on existing lists. The mildly annyoing edge case you need to learn about isn’t worth wiping out the whole broadly-useful language feature, or creating a great special-case inconsistency which would be more cognitive load to deal with, to eliminate.


Why are you comparing functions/closures with values? You can do the same in python:

  [list() for _ in range(4)]


> Why are you comparing functions/closures with values?

I'm not. The fun _ -> [] is needed because the argument is the element's index. That's just what List.init happens to expect, a function that takes an index and initializes the element, but the index is not needed here.


(I can’t respond to your other comment)

Ah I see, you’re saying that the construction of a list in F# mandates a lambda, thereby reducing one possible point of confusion. I could agree with that. But then it comes at a cost of comfort: [0]*4 has less boilerplate than the F# version. So it comes down to trade-offs again.


Are you saying f# special-cases something that looks like a closure, but isn’t in this one context? Because that, to me, seems like a much more grievous issue than the one at hand.


No. F# lambdas are closures. I was just saying that I'm not using the concept of closures to explain here. It's just a side effect of using the List.init function as a demonstration.


>That's the complaint, that [[]]*4 is not shorthand for list comprehensions and that it's something entirely different.

Well, of course. It's a shorthand for duplicating the list elements four times. In this case, the list contains a single reference to an empty list, do the result contains four references to an empty list.


And it's literally impossible for [[]]*4 to be a shorthand for a list comprehension, because nothing in Python can be a shorthand for a list comprehension. Instead, it is but a method call.


I mean, there is no reason Python couldn't special case something that looked like an operator call into shorthand for a comprehension instead of shorthand for a method call, other than the fact that it would make the parser more complex and make it harder to understand the language.

It would be bad for this case, though. As confusing as the particular case of:

  [[]] * 4
might be to people who haven't learned how it works, list multiplication doesn't just apply to single element lists, and is useful and usefully distinct from what people are suggesting the behavior should be for the operation based on this one case.


Well, Python is not Raku, so while it could be possible to make "[expr1, expr2, ..., exprN] * exprM" to mean "[*(expr1), *(expr2), ..., *(exprN) for _ in range(exprM)]", it would never happen.

Besides, that still doesn't help with the case of

    x = function_that_returns_a_list()
    x = x * 4
where there is no literal list expression.




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

Search: