Opened 4 years ago

Last modified 20 months ago

#4359 closed feature request

Implement lambda-case/lambda-if — at Version 9

Reported by: batterseapower Owned by:
Priority: high Milestone: 7.6.1
Component: Compiler Version: 7.1
Keywords: Cc: hydo@…, cmoore@…, hackage.haskell.org@…, uzytkownik2@…, leather@…, illissius@…, mikhail.vorozhtsov@…, anton.nik@…, dterei, g9ks157k@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description (last modified by simonpj)

I put together a patch for this Haskell' proposal (http://hackage.haskell.org/trac/haskell-prime/ticket/41)

    Prelude> (if then "Haskell" else "Cafe") False
    "Cafe"
    Prelude> (case of 1 -> "One"; _ -> "Not-one") 1
    "One"

There seems to be some support for integrating this proposal into GHC (see http://permalink.gmane.org/gmane.comp.lang.haskell.cafe/81366)

The attached patches implement the feature, test it and document it.

Change History (11)

Changed 4 years ago by batterseapower

Changed 4 years ago by batterseapower

comment:1 Changed 4 years ago by igloo

The motivating examples seem to be of the form

getArgs >>= case of
            [] -> error "No args"
            fs -> doit fs

so I wonder if a better extension would be:

mcase getArgs of
[] -> error "No args"
fs -> doit fs

comment:2 follow-up: Changed 4 years ago by malcolm.wallace@…

I would disagree that monadic bindings are the only (or even a major) use case.
Personally, I would often like the ability to have a standard lambda that can discriminate patterns on the value being bound.

foo = map (case of Alt1 a -> burble a
                   Alt2 | (x:xs) <- something    -> something more
                   otherwise -> def)

Lambda-case is more general than mcase.

comment:3 Changed 4 years ago by simonmar

+1 for lambda-case and lambda-if.

In a similar vein, I'd like to have multi-way if:

case | x < y     -> ...
     | x == y    -> ...
     | otherwise -> ...

comment:4 follow-up: Changed 4 years ago by simonmar

hmm, on second thoughts I revise that to +0 for lambda-case and lambda-if. They save a constant number of tokens (4), but the downside is that we have to adjust our mental parsers/typecheckers to recognise if then and case of as a lambda, and I'm not sure the gain in brevity is worth the loss of readability. (note that multi-way if doesn't suffer from this problem, it's just an abbreviation).

comment:5 in reply to: ↑ 2 Changed 4 years ago by igloo

Replying to malcolm.wallace@…:

I would disagree that monadic bindings are the only (or even a major) use case.

By "The motivating examples" I meant "The motivating examples in the thread linked to".

Personally, I would often like the ability to have a standard lambda that can discriminate patterns on the value being bound.

Do you have any realworld examples, OOI?

From a style point of view, using it point-free, as in your example, I think looks OK, but if it was being applied to something non-trivial (or even being composed with something non-trivial) I think it would be clearer if written using a let-bound function.

comment:6 Changed 4 years ago by hydo

  • Cc hydo@… added

comment:7 Changed 4 years ago by hydo

  • Cc cmoore@… added

comment:8 in reply to: ↑ 4 Changed 4 years ago by isaacdupree

Replying to simonmar:

hmm, on second thoughts I revise that to +0 for lambda-case and lambda-if. They save a constant number of tokens (4), but the downside is that we have to adjust our mental parsers/typecheckers to recognise if then and case of as a lambda, and I'm not sure the gain in brevity is worth the loss of readability. (note that multi-way if doesn't suffer from this problem, it's just an abbreviation).

"They save a constant number of tokens (4)" -- this is true, but the overhead is a bit more than just the tokens "\" "x" "->" (case) "x" (of ...). There's the mental complication of that name "x". You need to think, reading it: Is 'x' used anywhere later under the case/lambda?(no). And writing it: Are there variables named 'x' that we're accidentally shadowing, or otherwise using the same name confusingly?

I'm open to other suggestions than lambda-case/lambda-if that would help this mental-overhead issue.

comment:9 Changed 4 years ago by simonpj

  • Description modified (diff)
Note: See TracTickets for help on using tickets.