Lambda-case / lambda-if

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
53 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Lambda-case / lambda-if

Max Bolingbroke-2
Hi Cafe,

I implemented the proposed Haskell' feature lambda-case/lambda-if [1]
during the Haskell Implementors Workshop yesterday for a bit of fun.
The patches are online [2, 3].

The feature is demonstrated in this GHCi session:

$ inplace/bin/ghc-stage2 --interactive -XLambdaCase
GHCi, version 7.1.20101002: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> (if then "Haskell" else "Cafe") False
"Cafe"
Prelude> (case of 1 -> "One"; _ -> "Not-one") 1
"One"
Prelude> :q

Do you like this feature and think it would be worth incorporating
this into GHC? Or is it too specialised to be of use? If there is
enough support, I'll create a ticket and see what GHC HQ make of it.

Max

[1] http://hackage.haskell.org/trac/haskell-prime/ticket/41
[2] http://www.omega-prime.co.uk/files/LambdaCase-Testsuite.patch
[3] http://www.omega-prime.co.uk/files/LambdaCase-Compiler.patch
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Colin Paul Adams
>>>>> "Max" == Max Bolingbroke <[hidden email]> writes:

    Prelude> (if then "Haskell" else "Cafe") False
    Max> "Cafe"

My reaction is to ask:

Can you write this as:

(if then else) False  "Haskell"  "Cafe"

?
--
Colin Adams
Preston Lancashire
()  ascii ribbon campaign - against html e-mail
/\  www.asciiribbon.org   - against proprietary attachments
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Henning Thielemann
In reply to this post by Max Bolingbroke-2

On Sat, 2 Oct 2010, Max Bolingbroke wrote:

> Hi Cafe,
>
> I implemented the proposed Haskell' feature lambda-case/lambda-if [1]
> during the Haskell Implementors Workshop yesterday for a bit of fun.
> The patches are online [2, 3].
>
> The feature is demonstrated in this GHCi session:
>
> $ inplace/bin/ghc-stage2 --interactive -XLambdaCase
> GHCi, version 7.1.20101002: http://www.haskell.org/ghc/  :? for help
> Loading package ghc-prim ... linking ... done.
> Loading package integer-gmp ... linking ... done.
> Loading package base ... linking ... done.
> Loading package ffi-1.0 ... linking ... done.
> Prelude> (if then "Haskell" else "Cafe") False
> "Cafe"
> Prelude> (case of 1 -> "One"; _ -> "Not-one") 1
> "One"
> Prelude> :q
>
> Do you like this feature and think it would be worth incorporating
> this into GHC? Or is it too specialised to be of use? If there is
> enough support, I'll create a ticket and see what GHC HQ make of it.

Nice! Concerning if-then-else I would more like to see an according
function to go to Data.Bool, then we won't need more syntactic sugar like
if-then-else. However the lambda-case would be useful for me.
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Henning Thielemann
In reply to this post by Colin Paul Adams

On Sat, 2 Oct 2010, Colin Paul Adams wrote:

>>>>>> "Max" == Max Bolingbroke <[hidden email]> writes:
>
>    Prelude> (if then "Haskell" else "Cafe") False
>    Max> "Cafe"
>
> My reaction is to ask:
>
> Can you write this as:
>
> (if then else) False  "Haskell"  "Cafe"
>
> ?

Sure:

ifThenElse :: Bool -> a -> a -> a
ifThenElse True  x _ = x
ifThenElse False _ y = y

Prelude> ifThenElse False "Haskell" "Cafe"

(I have done this in utility-ht, and called it "if'".)
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Christopher Done
In reply to this post by Max Bolingbroke-2
On 2 October 2010 20:23, Max Bolingbroke <[hidden email]> wrote:
> Do you like this feature and think it would be worth incorporating
> this into GHC? Or is it too specialised to be of use? If there is
> enough support, I'll create a ticket and see what GHC HQ make of it.

Nice work! I like it and have wanted it for a while, and I know many
in the #haskell IRC channel would like it. The case is especially
useful. Maybe the if is only useful sometimes.

A benefit for lambda-case that I'll throw in the mix is:

main = do
  args <- getArgs
  case args of
    [path] -> do exists <- doesFileExist filepath
                 if exists
                    then readFile filepath >>= putStrLn
                    else error "file does not exist"
    _      -> error "usage: foo <filename>"

becomes:

main = do
  getArgs >>= case of
    [path] -> doesFileExist filepath
              >>= if then readFile filepath >>= putStrLn
                     else error "file does not exist"
    _      -> error "usage: foo <filename>"

There's nothing more annoying than having to introduce intermediate
bindings when you're going to immediate pattern match against it
immediately and never use it again. It's both annoying to have to
think of a variable name that makes sense and is not in scope or will
be in scope, and annoying to type it out, and it's just ugly. This is
*not* a special-case, it happens all the time and it's one of the few
things in the syntax I wish could be updated.

I vote yes, yes, and double yes!
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Christopher Done
I just had a look at hpaste.org, and, amusingly, the first paste has this:

      down <- openLazyURI "http://list.iblocklist.com/?list=bt_level1"
      case down of
            Left  _  -> error "Could not download file"
            Right bs -> do input <- bs
                                 ...

I can collect a huge list of instances of this annoying pattern from
Hackage and Google Code Search if it will encourage GHC HQ to make it
an extension.
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Ozgur Akgun
In reply to this post by Henning Thielemann
On 2 October 2010 19:33, Henning Thielemann <[hidden email]> wrote:

On Sat, 2 Oct 2010, Max Bolingbroke wrote:

... lambda-case/lambda-if ...

Nice! Concerning if-then-else I would more like to see an according function to go to Data.Bool, then we won't need more syntactic sugar like if-then-else. However the lambda-case would be useful for me.  

And I was just reading this entry in the wiki: http://www.haskell.org/haskellwiki/If-then-else

Best,
Ozgur


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Jan Christiansen
In reply to this post by Henning Thielemann

On 02.10.2010, at 20:35, Henning Thielemann wrote:

>
> On Sat, 2 Oct 2010, Colin Paul Adams wrote:

>>   Prelude> (if then "Haskell" else "Cafe") False
>>   Max> "Cafe"
>>
>> My reaction is to ask:
>>
>> Can you write this as:
>>
>> (if then else) False  "Haskell"  "Cafe"
>>
>> ?
>
> Sure:
>
> ifThenElse :: Bool -> a -> a -> a
> ifThenElse True  x _ = x
> ifThenElse False _ y = y
>
> Prelude> ifThenElse False "Haskell" "Cafe"


You can use a similar approach for case expressions ; )


import Prelude hiding ( catch )
import System.IO.Unsafe ( unsafePerformIO )
import Control.Exception ( catch, evaluate, PatternMatchFail )


caseOf :: a -> [a -> b] -> b
caseOf x = unsafePerformIO . firstMatch . map ($x)

firstMatch :: [a] -> IO a
firstMatch (x:xs) = catch (evaluate x) (handlePatternFail (firstMatch  
xs))

handlePatternFail :: a -> PatternMatchFail -> a
handlePatternFail x _ = x


test = (flip caseOf [\1 -> "One", \_ -> "Not-one"]) 1


Well, to tell the truth this does not work correctly as the following  
example shows.

test2 = (flip caseOf [\1 -> ((\2 -> "One") 3), \_ -> "Not-one"]) 1
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Felipe Lessa
In reply to this post by Christopher Done
On Sat, Oct 2, 2010 at 4:13 PM, Christopher Done
<[hidden email]> wrote:
> There's nothing more annoying than having to introduce intermediate
> bindings when you're going to immediate pattern match against it
> immediately and never use it again. It's both annoying to have to
> think of a variable name that makes sense and is not in scope or will
> be in scope, and annoying to type it out, and it's just ugly. This is
> *not* a special-case, it happens all the time and it's one of the few
> things in the syntax I wish could be updated.
>
> I vote yes, yes, and double yes!

I wholly agree with Christopher and for the same reason, +1.

Thanks,

--
Felipe.
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Brandon S Allbery KF8NH
In reply to this post by Jan Christiansen
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 10/2/10 15:27 , Jan Christiansen wrote:
> You can use a similar approach for case expressions ; )

There are several better (that is, not using unsafePerformIO) versions at
http://haskell.org/haskellwiki/Case .

- --
brandon s. allbery     [linux,solaris,freebsd,perl]      [hidden email]
system administrator  [openafs,heimdal,too many hats]  [hidden email]
electrical and computer engineering, carnegie mellon university      KF8NH
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.10 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkynmNsACgkQIn7hlCsL25XbOgCfdjFrXdR3PWJvPUif7VVfZZak
lOcAoMpp6l1+XOxU6vwCT+sgLI94l3Kx
=+gFp
-----END PGP SIGNATURE-----
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

wren ng thornton
In reply to this post by Christopher Done
On 10/2/10 3:13 PM, Christopher Done wrote:
> There's nothing more annoying than having to introduce intermediate
> bindings when you're going to immediate pattern match against it
> immediately and never use it again. It's both annoying to have to
> think of a variable name that makes sense and is not in scope or will
> be in scope, and annoying to type it out, and it's just ugly. This is
> *not* a special-case, it happens all the time and it's one of the few
> things in the syntax I wish could be updated.

+1.

In Mark Jones' new language, Habit, they have monadic versions of case
and if-then-else for precisely this reason.

I'm not sure if the (case of {...}) syntax is the best one to use for
this feature, but I'd love to get rid of those intermediate names for
monadic case expressions.

--
Live well,
~wren
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Max Bolingbroke-2
In reply to this post by Max Bolingbroke-2
Thanks to everyone who replied - it looks like this feature is enough
in demand that GHC HQ may want to accept it. I've created a ticket at
http://hackage.haskell.org/trac/ghc/ticket/4359

On 2 October 2010 14:23, Max Bolingbroke <[hidden email]> wrote:

> Hi Cafe,
>
> I implemented the proposed Haskell' feature lambda-case/lambda-if [1]
> during the Haskell Implementors Workshop yesterday for a bit of fun.
> The patches are online [2, 3].
>
> The feature is demonstrated in this GHCi session:
>
> $ inplace/bin/ghc-stage2 --interactive -XLambdaCase
> GHCi, version 7.1.20101002: http://www.haskell.org/ghc/  :? for help
> Loading package ghc-prim ... linking ... done.
> Loading package integer-gmp ... linking ... done.
> Loading package base ... linking ... done.
> Loading package ffi-1.0 ... linking ... done.
> Prelude> (if then "Haskell" else "Cafe") False
> "Cafe"
> Prelude> (case of 1 -> "One"; _ -> "Not-one") 1
> "One"
> Prelude> :q
>
> Do you like this feature and think it would be worth incorporating
> this into GHC? Or is it too specialised to be of use? If there is
> enough support, I'll create a ticket and see what GHC HQ make of it.
>
> Max
>
> [1] http://hackage.haskell.org/trac/haskell-prime/ticket/41
> [2] http://www.omega-prime.co.uk/files/LambdaCase-Testsuite.patch
> [3] http://www.omega-prime.co.uk/files/LambdaCase-Compiler.patch
>
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Conal Elliott
In reply to this post by Max Bolingbroke-2
I like it!

Are the other sections available as well, e.g.,

    (if False then else "Cafe") "Haskell" --> "Cafe"

- Conal

On Sat, Oct 2, 2010 at 11:23 AM, Max Bolingbroke <[hidden email]> wrote:
Hi Cafe,

I implemented the proposed Haskell' feature lambda-case/lambda-if [1]
during the Haskell Implementors Workshop yesterday for a bit of fun.
The patches are online [2, 3].

The feature is demonstrated in this GHCi session:

$ inplace/bin/ghc-stage2 --interactive -XLambdaCase
GHCi, version 7.1.20101002: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> (if then "Haskell" else "Cafe") False
"Cafe"
Prelude> (case of 1 -> "One"; _ -> "Not-one") 1
"One"
Prelude> :q

Do you like this feature and think it would be worth incorporating
this into GHC? Or is it too specialised to be of use? If there is
enough support, I'll create a ticket and see what GHC HQ make of it.

Max

[1] http://hackage.haskell.org/trac/haskell-prime/ticket/41
[2] http://www.omega-prime.co.uk/files/LambdaCase-Testsuite.patch
[3] http://www.omega-prime.co.uk/files/LambdaCase-Compiler.patch
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Ketil Malde-5
In reply to this post by Max Bolingbroke-2
Max Bolingbroke <[hidden email]> writes:

> [1] http://hackage.haskell.org/trac/haskell-prime/ticket/41

I tried to find anything about lambda-if in there, but failed  (Trac and
I aren't on very friendly terms, so it's probably my fault).  Is there
more information about the rationale and use cases for this?

> Prelude> (if then "Haskell" else "Cafe") False
> "Cafe"

Presumably, this extends to

> Prelude> (if False then else "Cafe") "Haskell"
> "Cafe"

and

> Prelude> (if then "Haskell" else) False "Cafe"
> "Cafe"

as well?

My gut reaction is that this doesn't buy a whole lot, and that it is
verbose and not very readable.  Any examples where this is a win?

> Prelude> (case of 1 -> "One"; _ -> "Not-one") 1
> "One"
> Prelude> :q

"case of" looks a bit weird, but I like the points brought up about
avoiding to name a one-use variable (e.g., getArgs >>= case of ...)
AFACS, this isn't easily implemented in Haskell either.

-k
--
If I haven't seen further, it is by standing in the footprints of giants
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re[2]: [Haskell-cafe] Lambda-case / lambda-if

Bulat Ziganshin-2
Hello Ketil,

Monday, October 4, 2010, 11:30:48 AM, you wrote:
>> Prelude> (if then "Haskell" else "Cafe") False

lambda-if is easily implemented in terms of usual functions.
and we even have one named bool:

bool: Bool -> a -> a -> a

lambda-case cannot be implemented as a function since we need
matching ability of "case"


--
Best regards,
 Bulat                            mailto:[hidden email]

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Re[2]: [Haskell-cafe] Lambda-case / lambda-if

Christopher Done
On 4 October 2010 10:55, Bulat Ziganshin <[hidden email]> wrote:
> Hello Ketil,
>
> Monday, October 4, 2010, 11:30:48 AM, you wrote:
>>> Prelude> (if then "Haskell" else "Cafe") False
>
> lambda-if is easily implemented in terms of usual functions.
> and we even have one named bool:
>
> bool: Bool -> a -> a -> a

I agree, in fact I have bool here:
http://hackage.haskell.org/packages/archive/higherorder/0.0/doc/html/Data-Bool-Higher.html

And the corresponding other types:

bool :: (a -> b) -> (a -> b) -> (a -> Bool) -> a -> b
list :: b -> ([a] -> b) -> [a] -> b
maybe :: b -> (a -> b) -> Maybe a -> b

But the case is especially useful for pattern matching.
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Donn Cave-4
In reply to this post by Ketil Malde-5
Quoth Ketil Malde <[hidden email]>,
> Max Bolingbroke <[hidden email]> writes:
...

>> Prelude> (if then "Haskell" else "Cafe") False
>> "Cafe"
>
> Presumably, this extends to
>
>> Prelude> (if False then else "Cafe") "Haskell"
>> "Cafe"
>
> and
>
>> Prelude> (if then "Haskell" else) False "Cafe"
>> "Cafe"
>
> as well?

I think you're not the first to ask.  Just out of curiosity, or is
there a use for these variations?

The reason for the initially proposed construct seems clear enough
to me, it's very much like `case'.  The difference is that of course
it's limited to True & False, so would naturally be used more with
more `composition', e.g.

  getargs >>= if then beTrue else beFalse . (==) ["-t"]

... and thus will quickly become unreadable with less trivial components.

        Donn
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Roel van Dijk-3
In reply to this post by Max Bolingbroke-2
I really like the lambda-case. There are dozens of places in my code
where I could use it.

Not so sure about the lambda-if. It is just as easily done using an
ordinary function.

lambda-case: +1
lambda-if: neutral
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Richard A. O'Keefe
In reply to this post by Ketil Malde-5

On 4/10/2010, at 8:30 PM, Ketil Malde wrote:
>
>> Prelude> (case of 1 -> "One"; _ -> "Not-one") 1
>> "One"
>> Prelude> :q
>
> "case of" looks a bit weird, but I like the points brought up about
> avoiding to name a one-use variable (e.g., getArgs >>= case of ...)
> AFACS, this isn't easily implemented in Haskell either.

Erlang manages fine with multiclause 'fun':

        (fun (1) -> "One" ; (_) -> "Not-one" end)(1)

ML manages fine with multiclause 'fn':

        (fn 1 => "one" | _ => "not-one")(1)

In both cases, the same notation is used for multiclause lambda as
for single clause lambda.  It seems excessively ugly to use
completely different notation depending on the number of alternatives,
especially when one of the notations has another, much more common,
and distinct usage.

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Lambda-case / lambda-if

Donn Cave-4
Quoth "Richard O'Keefe" <[hidden email]>,
...

> Erlang manages fine with multiclause 'fun':
>
> (fun (1) -> "One" ; (_) -> "Not-one" end)(1)
>
> ML manages fine with multiclause 'fn':
>
> (fn 1 => "one" | _ => "not-one")(1)
>
> In both cases, the same notation is used for multiclause lambda as
> for single clause lambda.  It seems excessively ugly to use
> completely different notation depending on the number of alternatives,
> especially when one of the notations has another, much more common,
> and distinct usage.

Just to be sure, are you saying, rather than

    case of
        1 -> f
        2 -> g

you'd like to see \ support pattern matching etc. like named functions -

    \ 1 -> f
      2 -> g

?
        Donn
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
123