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

change cond else behaviour #38

Open
2 tasks done
spdegabrielle opened this issue Jul 18, 2019 · 8 comments
Open
2 tasks done

change cond else behaviour #38

spdegabrielle opened this issue Jul 18, 2019 · 8 comments

Comments

@spdegabrielle
Copy link
Sponsor Member

spdegabrielle commented Jul 18, 2019

change cond else behaviour;

@AlexKnauth
Copy link
Member

I agree with the first point, replacing fallthrough behavior (when there's no else and all the conditions are false) from void to error. There have been so many bugs written by myself and other people that would have been caught much sooner if an error were the default fallthrough behavior.

However, I don't see any reason to change cond and match to use an #:else keyword over of an else literal recognized by binding.

@spdegabrielle
Copy link
Sponsor Member Author

However, I don't see any reason to change cond and match to use an #:else keyword over of an else literal recognized by binding.

I don’t understand the rationale for #:else either.

@sorawee
Copy link
Contributor

sorawee commented Jul 18, 2019

I think the rationale is:

(let ([else #f])
  ;; a lot of code
  (cond
    [else 1]))

results in #<void>. But by looking at

  (cond
    [else 1])

locally, readers might assume that it will return 1.

@AlexKnauth
Copy link
Member

AlexKnauth commented Jul 18, 2019

I think that's acceptable because you can tell just by mousing over it in DrRacket that else is a local variable looking at the check-syntax highlighting or arrows

Plus the programmer presumably meant to override the meaning of else in a case like that

@gus-massa
Copy link

The idea is that an else inside a cond is special, so it's better that it looks like something special like a keyword #:else instead of like a normal identifier else. This is similar to the #:when and #:break inside a for. (Note that there is a proposal to modify for to move in the opposite direction #31.)

@AlexKnauth
Copy link
Member

Perhaps this should be separated into two issues. The discussion on behavior/runtime-semantics for point (1) will be different from the discussion on syntax for point (2)

@AlexKnauth
Copy link
Member

So @spdegabrielle should we remove point (1) and move discussion on that to #39? Most of the discussion in comments seems to be on point (2) here

@rocketnia
Copy link

The way I remember hearing this explained recently is that most DSLs should look up transformer bindings, and if it doesn't make sense for them to do so, then they're really not dealing with the meanings of symbols and they're instead dealing with names. Users pass in symbols when they intend to pass in their meanings (or to bind them to new meanings), and they pass in keywords when they intend for the name to matter.

In my opinion, the user really intends to pass in keywords by meaning too, and the root cause is a bit different. When a DSL is simple enough that it doesn't even have recursive cases in its syntax, that leads to a couple of consequences:

  • It can get away with not having parentheses because it doesn't nest.

  • It can get away with not having user-definable operators because there's no combinatorial explosion. Nearly all the useful syntaxes can be anticipated by the designer and made available right out of the box.

These are roughly the conditions where Racket uses keywords instead of symbols.

If it were up to me, I'd like to go with parentheses and an extension DSL anyway, just to set the right example so people don't paint themselves into a corner by starting the keyword way and then realizing their DSL has grown too big to sustain it. But maybe that means people who are trying to learn what cond means will get derailed trying to understand the very advanced and mostly useless concept of "condition transformer" or "conditional branch transformer" or something, so I can't say my favorite approach is a very good one here. :-p

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

No branches or pull requests

5 participants