Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding for/else? #3298

Closed
2rs2ts opened this issue Dec 31, 2013 · 12 comments
Closed

Adding for/else? #3298

2rs2ts opened this issue Dec 31, 2013 · 12 comments

Comments

@2rs2ts
Copy link

2rs2ts commented Dec 31, 2013

Would it be possible to work in a for/else construct? Such as in python:

for x in lst:
    if cond(x):
        do_stuff_with(x)
        break
else:
    do_other_stuff()

Currently I'd write my coffeescript like this to do the same:

found = false
for x in lst
    if cond x
        found = true
        do_stuff_with x
        break
if not found
    do_other_stuff()

It's just a little syntactic sugar, but it'd be nice.

@vendethiel
Copy link
Collaborator

ref satyr/coco#75

@epidemian
Copy link
Contributor

I've always found Python's for/else construct confusing. I'd much rather prefer Coco's semantics of only executing the else branch when the loop body is not executed (i.e., when the array/object is empty in case of for loops or when the condition is false from the start on while loops).

That being said, having an analogous syntax to Python but with a drastically different meaning doesn't sound like a good decision either.

@bjmiller
Copy link

bjmiller commented Jan 1, 2014

Better to think in coffee for this one. This would work:

found = false
(do_stuff_with(x); found = true) for x in lst when cond(x)
do_other_stuff() unless found

(As a mild brain teaser, does anyone think they can make this a little more tight?)

Anyway, I don't think this is a feature worth adding, since there's generally a nicer and more fluent way to achieve the same thing.

@lydell
Copy link
Collaborator

lydell commented Jan 1, 2014

@bjmiller you could remove the first line, couldn't you?

(do_stuff_with(x); found = true) for x in lst when cond(x)
do_other_stuff() unless found

(Unless you reuse the found variable. So probably not such a good idea.)

@nfour
Copy link

nfour commented Jan 1, 2014

I'm just going to put it out there; syntax for an else when an enumerable item is "empty" is silly. The way Python does it is the use-case that seems most reasonable, as it's far more correct to actually check if the thing you're about to loop over is actually what you expect it to be if you're going to do something different if it's empty.

@2rs2ts proposal seems useful, the coco issue seems 2edgy4me.

@vendethiel
Copy link
Collaborator

I need for/else pretty often (for item in items then display else say "no products!") but I've never needed python's version.

@nfour
Copy link

nfour commented Jan 1, 2014

@Nami-Doc But you're supposed to write;
if Object.keys(object).length then display else say "chicken fried rice"
or array.length, or some other predefined way to determine emptiness.

It's like you don't want performant code!

@vendethiel
Copy link
Collaborator

considering Object.keys has to be shimmed on old browser (or can be slow on large arrays, I suppose), I don't think it's more performant than a bool value.

@xixixao
Copy link
Contributor

xixixao commented Jan 2, 2014

-1 Too specific of a case vs. great confusion of where the hell is the if for that else.

@nfour
Copy link

nfour commented Jan 2, 2014

http://jsperf.com/empty-enumerable-loop-or-check

Turns out it's inconclusive anyway. If the object is filled, the for loop is slowest, if it's not filled the for loop is fastest (I'd personally just write if obj?.knownKey myself). Blah blah it's not important.

I also -1 as even though I run into this use case a bit, it seems unintuitive for shorthanding.

@edemaine
Copy link
Contributor

Sorry to revive an old issue, but lots of the discussion has been around Coco's for...else semantics (which seems not especially useful), and not so much about Python's for...else semantics, which I've used a lot and find very helpful. Yes, you can use the idiom:

found = false
for ...
  if ...
    found = true
    break
unless found
  ...

But the idea is to avoid having to write the idiom (2-3 lines worth), and just say

for ...
  if ...
    break
else
  ...

This is especially useful if there's lots of computation between the for and if, many break cases, etc. It's actually error prone to have to write found = true next to each break.

Another fun example you can do with these semantics is to break out of two loop levels:

for x in ...
  for y in ...
    break if ...
  else
    continue
  break

Admittedly, this is pretty unreadable... but it is convenient. :-)

Perhaps another name than else would make people happier? In any case, I think it deserves further discussion. I definitely miss this feature coming from Python.

@jashkenas
Copy link
Owner

jashkenas commented Nov 29, 2016

Python's for/else feature isn't good enough for us to want to add to JavaScript. For a good introduction, see:

http://python-notes.curiousefficiency.org/en/latest/python_concepts/break_else.html

The first section, Reasons for Confusion, is especially relevant.

In any case, doing manual found = true searching through loops probably isn't what you should be writing most of the time. Instead of:

found = false
for item in list
  if item.property is 'value'
    found = item
    break
if found
  ...

Try something like:

found = where list, property: 'value'
if found ...

Finally, from that page:

The simplest approach for any new language to take to avoid the confusion encountered in relation to this feature of Python would be to just leave it out altogether.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants