Tuesday Nov 10, 2009

Church booleans vs. JavaFX (vs. Haskell)

Recently I've started to read Types and Programming Languages with which I normally use Haskell([1]) for book's interpreters implementation and for helping to solve some exercises. But since I've joined the NetBeans JavaFX support development I'm also learning JavaFX language. And in order to learn the JavaFX language a bit more, I chose ¨perfect¨ ;) usecase for it - Church encoding of boolean values ( Church booleans). Below is the result. For comparison and might be for better understanding I'm also attaching Haskell (which naturally fits much better for the exercise) solution which is kind of easier to read, since it's just almost direct translation of Lambda Calculus notation.

Small complains against JavaFX:

  • compiler type-inference failed in result sequence thus as operator has to be utilized.
  • I need to provide function signature for a bunch of parameters as well. Those could be also inferred. (I've provided type signatures for Haskell just for better readability. Note that they might be all deleted and GHC will infer all types correctly)
  • other problem causing verbosity is due to the impossibility to specify type alias. As might be done in Haskell with: type ChurchBool = forall a . a -> (a -> a) . Probably could be handy in JavaFX here and there as well.

To be fair JavaFX is aimed for quite different domain then Haskell for which this solution fits really well. And might be I misunderstood or do not know some JavaFX syntax/features which would make the code neater.

And sure, this is artificial and probably not that useful case :) But one usually understand the language's dark corners by non-standard language utilization. Try to rewrite some monads into JavaFX. So far I've failed to come with at least a bit sane solution for Maybe monad. Anybody? :)

Haskell sources:

 1 {-# LANGUAGE RankNTypes #-}
 2 
 3 import Prelude hiding (and, or, not)
 4 
 5 type ChurchBool = forall a . a -> (a -> a)
 6 
 7 -- tru = λt. λf. t
 8 tru :: ChurchBool
 9 tru = \\t -> \\f -> t
10 
11 -- fls = λt. λf. f
12 fls :: ChurchBool
13 fls = \\t -> \\f -> f
14 
15 -- test = λl. λm. λn. l m n
16 test :: ChurchBool -> a -> a -> a
17 test = \\l -> \\m -> \\n -> l m n
18 
19 -- and = λb. λc. b c fls
20 and :: ChurchBool -> ChurchBool -> ChurchBool
21 and = \\b -> \\c -> b c fls
22 
23 -- or = λb. λc. b tru c
24 or :: ChurchBool -> ChurchBool -> ChurchBool
25 or = \\b -> \\c -> b tru c
26 
27 -- not = λb. b fls tru
28 not :: ChurchBool -> ChurchBool
29 not = \\b -> b fls tru
30 
31 -- just utility tester
32 :: ChurchBool -> String
33 t b = test b "tru" "fls"
34 
35 main =
36   mapM_ putStrLn
37     [ "-- tru test"
38     , t tru
39 
40     , "-- fls test"
41     , t fls
42 
43     , "-- and test"
44     , t $ and tru tru
45     , t $ and tru fls
46     , t $ and fls tru
47     , t $ and fls fls
48 
49     , "-- or test"
50     , t $ or tru tru
51     , t $ or tru fls
52     , t $ or fls tru
53     , t $ or fls fls
54 
55     , "-- not test"
56     , t $ not tru
57     , t $ not fls
58     ]
59 

JavaFX sources:

 1 package javafxtester;
 2 
 3 def tru = function(t) { function(f) { t } }
 4 def fls = function(t) { function(f) { f } }
 5 
 6 def test = function(l:function(:Object):(function(:Object):Object)) {
 7     function(m) {
 8         function (n) {
 9             l(m)(n)
10         }
11     }
12 }
13 
14 def and_ = function(b:function(:Object):(function(:Object):Object)) {
15     function(c) {
16         b(c)(fls)
17     }
18 }
19 
20 def or_ = function(b:function(:Object):(function(:Object):Object)) {
21     function(c) {
22         b(tru)(c)
23     }
24 }
25 
26 def not_ = function(b:function(:Object):(function(:Object):Object)) {
27     b(fls)(tru)
28 }
29 
30 // just utility tester
31 function t(b:function(:Object):(function(:Object):Object)) {
32     test(b)("tru")("fls")
33 }
34 
35 var results =
36     [ "-- tru test"
37     , t(tru)
38 
39     , "-- fls test"
40     , t(fls)
41 
42 
43     , "-- and test"
44     , t(and_(tru)(tru) as function(:Object):(function(:Object):Object))
45     , t(and_(tru)(fls) as function(:Object):(function(:Object):Object))
46     , t(and_(fls)(tru) as function(:Object):(function(:Object):Object))
47     , t(and_(fls)(fls) as function(:Object):(function(:Object):Object))
48 
49     , "-- or test"
50     , t(or_(tru)(tru) as function(:Object):(function(:Object):Object))
51     , t(or_(tru)(fls) as function(:Object):(function(:Object):Object))
52     , t(or_(fls)(tru) as function(:Object):(function(:Object):Object))
53     , t(or_(fls)(fls) as function(:Object):(function(:Object):Object))
54 
55     , "-- not test"
56     , t(not_(tru) as (function(:Object):(function(:Object):Object)))
57     , t(not_(fls) as (function(:Object):(function(:Object):Object)))
58     ];
59 
60 for (r in results) println(r);
[1] yup, I know that the TAPL's language of choice is OCaml but I'm just reading through Real World Haskell. Nothing personal against OCaml :) Similar folks might be interested in tapl-haskell project.
About

Martin Krauskopf

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today