Update of /cvsroot/hoc/hoc/docs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4075 Modified Files: Accessing_Other_Frameworks.pod Appendices.pod Creating_an_Objective-C_Class_in_Haskell.pod Introduction.pod Makefile.in Mapping_Types.pod Quick_Start.pod Added Files: Tools.pod Log Message: Massive documentation update. See diff for more information :-) Index: Accessing_Other_Frameworks.pod =================================================================== RCS file: /cvsroot/hoc/hoc/docs/Accessing_Other_Frameworks.pod,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- Accessing_Other_Frameworks.pod 6 May 2004 15:51:23 -0000 1.1 +++ Accessing_Other_Frameworks.pod 19 May 2004 15:59:28 -0000 1.2 @@ -1,7 +1,16 @@ =head1 Accessing Other Frameworks from Haskell -=head2 Using F<ifgen> +This section is not written yet: please write to the I<hoc-users> +mailing list (see L<http://hoc.sourceforge.net/support.html>) for +assistance or, have a look at the HOC source code yourself. -=head3 Binding Scripts +=begin comment +TODO :) + +=for comment =head2 Using F<ifgen> + +=for comment =head3 Binding Scripts + +=end comment Index: Introduction.pod =================================================================== RCS file: /cvsroot/hoc/hoc/docs/Introduction.pod,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- Introduction.pod 19 May 2004 08:38:47 -0000 1.5 +++ Introduction.pod 19 May 2004 15:59:28 -0000 1.6 @@ -41,7 +41,9 @@ data types representing the Objective-C class hierarchy, and methods and selectors which enable HOC to communicate with Objective-C frameworks. If you are familiar with other Haskell -interface generators such as F<c2hs> or F<GreenCard>, HOC's +interface generators such as F<c2hs> +<L<http://www.cse.unsw.edu.au/~chak/haskell/c2hs/>> or +F<GreenCard> <L<http://www.haskell.org/greencard/>>, HOC's I<ifgen> tool does the same job, but for creating bindings to Objective-C classes instead. @@ -50,8 +52,6 @@ F<Cocoa> on S<Mac OS X>), but you can build your own bindings with F<ifgen> if required. -=for comment XXX insert hyperlink to c2hs etc - =item * Haskell-Friendly HOC was designed from the very beginning to be as 'Haskell-like' @@ -66,20 +66,17 @@ HOC's primary platform is S<Mac OS X>, Apple's modern UNIX-based operating system. However, HOC does provides preliminary support -for the GNUstep platform, and has been lightly toasted, err, -tested, with GNUstep on Linux. - -=for comment XXX insert link to GNUstep +for the GNUstep platform <L<http://www.gnustep.org/>>, and has +been lightly toasted, err, tested, with GNUstep on Linux. =head2 Requirements -HOC requires the Glasgow Haskell Compiler (GHC) 6.2 or later to -build. We use the latest features provided by GHC, such as -Template Haskell, to implement many parts of HOC, and it would be -impossible (as opposed to just plain hard) to port these -implementations to work with older versions of GHC. - -=for comment XXX: insert link to GHC +HOC requires the Glasgow Haskell Compiler (GHC) 6.2 +<L<http://www.haskell.org/ghc/>> or later to build. We use the +latest features provided by GHC, such as Template Haskell, to +implement many parts of HOC, and it would be impossible (as +opposed to just plain hard) to port these implementations to work +with older versions of GHC. =head2 Assumed Knowledge @@ -95,10 +92,6 @@ way. Hell, this author has done IO in Haskell for years and doesn't pretend to understand monads ... -=head2 Getting Started - -TODO: Building HOC. - =for comment Modeline for vi(m) vi:sw=2 tw=65 Index: Quick_Start.pod =================================================================== RCS file: /cvsroot/hoc/hoc/docs/Quick_Start.pod,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- Quick_Start.pod 19 May 2004 08:38:47 -0000 1.8 +++ Quick_Start.pod 19 May 2004 15:59:28 -0000 1.9 @@ -77,12 +77,145 @@ Hopefully, the code listing above will give you a good idea about how to write Haskell code that sends messages to Objective-C -objects. For more detail, see Chapter 3. - -=for comment XXX: link to chapter 3 +objects. For more detail, see the chapter on +L<"Mapping Objective-C Concepts to Haskell">. =head2 A Simple GUI Application +Preface: This section presumes that you've written a Cocoa +application before with Objective-C, so that you understand the +basic development process and design patterns involved with Cocoa +programs, such as Model-View-Controller and how to use Interface +Builder. If you don't know any of this, you'll have to do some +background reading on Cocoa. Apple provides a simple tutorial at +L<http://developer.apple.com/documentation/Cocoa/Conceptual/ObjCTutorial/index.html?http://developer.apple.com/documentation/Cocoa/Conceptual/ObjCTutorial/chapter01/chapter_1_section_1.html>, +but if you're after something more comprehensive, this author has +read and highly recommends the book "Cocoa Programming for Mac OS +X", by Aaron Hillegass: +L<http://www.bignerdranch.com/products/cocoa1.shtml>. + +Say you've got a simple Haskell module: for this example, we'll +use the F<ExpressionParser.hs> module from the +F<Samples/ExpressionParser> directory of the HOC source +distribution. The code is short and schweet: + + module ExpressionParser + + where + + import Text.ParserCombinators.Parsec + import Text.ParserCombinators.Parsec.Expr + + expr :: Parser Integer + expr = buildExpressionParser table factor <?> "expression" + + table = [ [op "*" (*) AssocLeft, op "/" div AssocLeft] + , [op "+" (+) AssocLeft, op "-" (-) AssocLeft] ] + where + op s f assoc = Infix (do { string s; return f }) assoc + + factor = do { char '('; x <- expr; char ')'; return x } + <|> number + <?> "simple expression" + + number :: Parser Integer + number = do { ds <- many1 digit; return (read ds) } <?> "number" + +Now, you want to wrap a GUI around this module so that people can +use it without loading GHC or the Apple Terminal application: see +L<http://localhost/~andrep/hoc/screenshots/ExpressionParser_view.png> +for a screenshot of what the GUI will look like. From +a programing perspective, the GUI consists of: + +=over 4 + +=item An I<expressionEntry> outlet + +This is where the user types in the expression which they want +the answer to. + +=item An I<evaluateExpression> action + +The method which will be called when the user clicks on the +button, or presses Enter in the I<expressionEntry> text field. + +=item An I<evaluation> outlet + +Where the answer to the expression evaluation will be displayed. + +=back + +For this example, we assume that you've created and instantiated +an C<EPController> object in Interface Builder which the GUI view +will be connected to. The question is, of course: how do you +write this C<EPController> object in Haskell? The answer: like +this ... + + {-# OPTIONS -fglasgow-exts #-} + + module EPController where + + import Cocoa hiding (parse) + import ExpressionParser + import Selectors + import Text.ParserCombinators.Parsec (parse) + + $(declareClass "EPController" "NSObject") + + $(exportClass "EPController" "ep_" + [ Outlet "expressionEntry" [t| NSTextField () |] + , Outlet "evaluation" [t| NSTextField () |] + , InstanceMethod Selectors.info_evaluateExpression ]) + + obj #. var = obj # getIVar var + + ep_evaluateExpression _ self = do + -- Get the expressionEntry outlet text field from this object, and get + -- what the user typed as a Haskell string + expression <- self #. _expressionEntry >>= stringValue >>= haskellString + -- Parse the expression + case (parse expr "" expression) of + Left err -> + -- Parsing returned an error: display it in the output text field + self #. _evaluation >>= setStringValue (toNSString $ "Error " ++ show err) + Right answer -> + -- Parsing was successful: display the answer + self #. _evaluation >>= setStringValue (toNSString $ show answer) + +Additionally, you'll need to write a C<Selectors.hs> module, which +contains any additional selector names that aren't in Cocoa. +This enables HOC to statically type check your function names and +make sure that they exist. You can call the module whatever you +like: the important bit is that the C<declareSelector> function +you'll be using I<must> be in a different module from the +C<declareClass> and C<exportClass> functions, due to a limitation +of Template Haskell. e.g.: + + {-# OPTIONS -fglasgow-exts #-} + + module Selectors where + + import AppKit.NSButton + + $( declareSelector "evaluateExpression:" [t| forall a. NSButton a -> IO () |] ) + +That comprises the code for your graphical application. You'll +still need to produce a F<.app> application bundle to run your +GUI application though: to do this, you could manually make the +F<.app> bundle, which is rather tedious. A better idea would be +to use Xcode to generate a boilerplate bundle for you and +customise that, or use the F<hocnewapp> tool (described in the +L<"Tools"> section) supplied with HOC, which performs a similar +task. Once you've produced the F<Contents/> directory layout +required for the bundle, you can then use the F<hocwrap> tool +(again described in L<"Tools">) to wrap your Haskell executable +to produce the final L<.app> directory (or hand-roll it yourself, +if you're into masochism). + +For complete code examples, see the F<ExpressionParser>, +F<Browser>, and F<Editor> applications in HOC's F<Samples/> +directory. + =for comment Modeline for vi(m) vi:sw=2 tw=65 Index: Appendices.pod =================================================================== RCS file: /cvsroot/hoc/hoc/docs/Appendices.pod,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- Appendices.pod 6 May 2004 15:52:35 -0000 1.2 +++ Appendices.pod 19 May 2004 15:59:28 -0000 1.3 @@ -2,8 +2,94 @@ =head2 Building HOC +HOC is distributed as a standard UNIX tarball (F<.tar.bz2> file), and +uses GNU I<autoconf> for its build system. Building HOC should +be a simple matter of the standard autoconf build mantra: + + ./configure + make + make install + +See the F<README.txt> file in the HOC distribution for the most +up-to-date build information. + +Building HOC from a CVS repository is only slightly more +involved: see the F<BUILDING.CVS> file in your checked out CVS +directory (which is not included in proper release tarball) for +more information. + =head2 Template Haskell in a Nutshell +I<Template Haskell is an extension to Haskell 98 that allows you +to do type-safe compile-time meta-programming, with Haskell both +as the manipulating language and the language being manipulated.> +E<mdash> from the Template Haskell webpage at +<L<http://www.haskell.org/th/>>. + +From a HOC user's viewpoint, Template Haskell makes lots of +things possible in HOC that are not possible without it, and +greatly simplifies the HOC API that you use to declare new +classes. In the L<"The Class Creation API"> section, the two +functions C<declareClass> and C<exportClass> "template" functions +were described. These are functions which have the mysterious +output type C<Q [Dec]>: to put it simply, the output of these +template functions are actually I<Haskell code>. Just as +functional languages such as Haskell can treat functions as +first-class entities, Template Haskell allows Haskell I<code> to +be treated as a first-class entity: you can pass code around to +other functions, inspect the code, change it, and pass that new +code to yet more functions. (If you're familiar with compilers, +the code that's passed around is actually a data structure that +represents the I<abstract syntax tree>: you can walk the tree and +add, change or remove nodes at your leisure.) + +Of course, as well as manipulating code, you can also I<execute> +these first-class code thingys, which is what the odd-looking +C<$(...)> syntax does. That tells GHC to execute the code +fragment inside the brackets: in Template Haskell terminology, +this is called I<splicing> in code. So, when you use template +functions such as C<exportClass>, they actually generate code +based on the parameters you give it, and immediately splice the +code in, writing out possibly hundreds of declarations and +functions for you invisibly. + +Of course, this appendix only covers Template Haskell as it +applies to HOC: see the Template Haskell webpage (link given +above) for more information on it, what you can do with it, and +why it (and meta-programming in general) kicks ass. + +=head2 History + +A long time ago, in a galaxy far, far away ... err, wait, wrong +chapter. Ahem. + +The first development snapshot of HOC came out in January 2003, +in a humble announcement to the I<glasgow-haskell-users> mailing +list by Wolfgang Thaller. While it worked, it was half of an +experiment with Template Haskell, and half a proof-of-concept, +rather than intending to be a proper language binding. + +During HOC's development, another Haskell to Objective-C binding +was being developed, named Mocha. Mocha was the result of +AndrE<eacute> Pang's thesis on Binding Haskell to Object-Oriented +and Component Systems +<L<http://www.algorithm.com.au/files/reflection/reflection.pdf>>, +and it, like many thesis implementations, was also more of +a proof-of-concept rather than a real, useful piece of software. + +The authors of HOC and Mocha met at the Haskell Implementor's +Meeting in Stockholm, Sweden later in 2003, and sat down to try +to reconcile the two projects. HOC was a very different beast +from Mocha: HOC wasn't typed at all (e.g. all Objective-C objects +were represented using only the one C<ID> type), for instance. +Mocha, being the result of a thesis on integrating Haskell with +object-oriented systems, was focused very much at bringing +object-oriented style overloading into the Haskell world. +Wolfgang Thaller did the heavy lifting and rewrote HOC from +scratch using many of the ideas from Mocha and AndrE<acute>'s +thesis, and the result is what you have today: a more supported, +stable Objective-C binding than would be possible without both +authors supporting each other. =for comment Modeline for vi(m) vi:sw=2 tw=65 Index: Makefile.in =================================================================== RCS file: /cvsroot/hoc/hoc/docs/Makefile.in,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- Makefile.in 19 May 2004 08:40:51 -0000 1.8 +++ Makefile.in 19 May 2004 15:59:28 -0000 1.9 @@ -18,10 +18,9 @@ SOURCE_PODS = Introduction.pod \ Quick_Start.pod \ Mapping_Types.pod \ - Accessing_Core_Frameworks.pod \ Accessing_Other_Frameworks.pod \ Creating_an_Objective-C_Class_in_Haskell.pod \ - History.pod \ + Tools.pod \ Appendices.pod \ $(NULL) @@ -61,6 +60,10 @@ dist: HOC.html +# failed attempt at getting Safari to print to PDF; see +# http://64.233.167.104/search?q=cache:F2D2JTT0b98J:www1.odn.ne.jp/~cge02410/panther/system_events_003.html+applescript+safari+print+pdf&hl=en for more info +# HOC.pdf: HOC.html + install: true Index: Creating_an_Objective-C_Class_in_Haskell.pod =================================================================== RCS file: /cvsroot/hoc/hoc/docs/Creating_an_Objective-C_Class_in_Haskell.pod,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- Creating_an_Objective-C_Class_in_Haskell.pod 12 May 2004 05:44:14 -0000 1.4 +++ Creating_an_Objective-C_Class_in_Haskell.pod 19 May 2004 15:59:28 -0000 1.5 @@ -48,10 +48,8 @@ C<exportClass>. Note that these functions are I<Template Haskell> (TH) functions, so you'll need to use Template Haskell's special C<$(...)> syntax to use them. (If you don't know what -Template Haskell is, see the next section which gives a very -quick overview about what it is.) - -=for comment XXX: Insert hyperlink to next section +Template Haskell is, see the L<"Template Haskell in a Nutshell"> +appendix which gives a very quick overview about what it is.) =head3 The C<declareClass> Function @@ -69,8 +67,6 @@ sits at the root of an object hierarchy (such as I<NSObject> or I<NSProxy>). -=for comment XXX: Maybe turn above into a type signature - For example, $(declareClass "MyDocument" "NSDocument") @@ -78,8 +74,6 @@ declares a new class named I<MyDocument> which is a subclass of I<NSDocument>. (Imaginative, huh?) -=for comment XXX: Wolfgang -- is the above correct? - =head3 The C<exportClass> Function After using the C<declareClass> Template Haskell function to @@ -139,10 +133,7 @@ Hopefully the type information will inform you about what arguments you need to provide to each of the data contructors to -produce a C<ClassMember>. (Refer to the documentation about -C<ClassMember>s if you need more help with them.) - -=for comment XXX: document & provide link to ClassMember +produce a C<ClassMember>. Here's an example of what this particular argument might look like (taken directly from the @@ -188,9 +179,9 @@ The I<HaskellDocument> class in the above example only implemented methods whose types were already known because the -selector was already defined somewhere in Cocoa. If you've just -used InterfaceBuilder to place a small button labeled with the -Greek letter Pi in the lower-left corner of your window and +selector was already defined somewhere in Cocoa. If you've used +InterfaceBuilder to place a small button labelled with the Greek +letter I<Pi> in the lower-left corner of your window and connected it to a method named C<smallPiClicked:>, then you'll need to declare that selector yourself using the C<declareSelector> template function, which has the following @@ -202,20 +193,22 @@ So for the C<smallPiClicked:> selector you might write: - $(declareSelector "smallPiClicked:" [t| forall a. ID a -> IO () |] + $( declareSelector "smallPiClicked:" [t| forall a. ID a -> IO () |] ) The Objective-C selector name "smallPiClicked:" will be -automatically mangled to C<smallPiClicked>. If you don't like -this, you can use C<declareRenamedSelector> instead: +automatically mangled to C<smallPiClicked> (as per the rules +given in the L<"Selectors"> section above). If you don't like this, +you can use C<declareRenamedSelector> instead: - $(declareRenamedSelector "smallPiClicked:" "haskellNameForThisSelector" - [t| forall a. ID a -> IO () |]) + $( declareRenamedSelector "smallPiClicked:" "haskellNameForThisSelector" + [t| forall a. ID a -> IO () |] ) Due to a limitation of Template Haskell, you cannot put this declaration in the same module as your C<exportClass> -declaration. This is because identifiers declared by Template -Haskell "splices" are not available to other splices within the -same module. +declaration: you'll have to put them in another module and +C<import> that module instead. (This is because identifiers +declared by Template Haskell "splices" are not available to other +splices within the same module.) =for comment Modeline for vi(m) vi:sw=2 tw=65 --- NEW FILE: Tools.pod --- =head1 Tools =head2 F<hocwrap> =head2 F<hocnewapp> =for comment Modeline for vi(m) vi:sw=2 tw=65 Index: Mapping_Types.pod =================================================================== RCS file: /cvsroot/hoc/hoc/docs/Mapping_Types.pod,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- Mapping_Types.pod 19 May 2004 08:38:47 -0000 1.5 +++ Mapping_Types.pod 19 May 2004 15:59:28 -0000 1.6 @@ -1,6 +1,6 @@ -=head1 Mapping Objective-C Concepts to Haskell's Type System +=head1 Mapping Objective-C Concepts to Haskell -=head2 Objective-C Objects +=head2 Objects & Classes =head3 Classes @@ -21,22 +21,28 @@ C<alloc> message to the I<NSMovie> class object, write C<_NSMovie # alloc>. -=head3 Protocols +=head3 Protocols & Protocol Adoptions -=begin comment +=for comment XXX: fix up this section -Yes, formal protocols. Luckily, they're very rarely used in -Cocoa. It's only an ifgen issue; the current ifgen just -generates ID for all id<Foo> types. For id<Foo,Bar> used as -a parameter, it should generate (Foo (ID a), Bar (ID a)) => ID a. -For return values id<Foo,Bar>, we'll have to define a special -type ID_Bar_Foo and declare instances for Foo and Bar for it. The -only difficult part should be to avoid defining those types too -often... +This section of the documentation hasn't been written yet, but in +the meantime, you may find the following note from Wolfgang +Thaller useful: -=end comment + Yes, formal protocols. Luckily, they're very rarely used in + Cocoa. It's only an ifgen issue; the current ifgen just + generates ID for all id<Foo> types. For id<Foo,Bar> used as + a parameter, it should generate (Foo (ID a), Bar (ID a)) => ID + a. For return values id<Foo,Bar>, we'll have to define + a special type ID_Bar_Foo and declare instances for Foo and Bar + for it. The only difficult part should be to avoid defining + those types too often... -=head3 Protocol Adoptions +=head3 Categories + +This section is not written yet: please write to the I<hoc-users> +mailing list (see L<http://hoc.sourceforge.net/support.html>) for +assistance or, have a look at the HOC source code yourself. =head3 Specific Classes @@ -58,8 +64,6 @@ NSStringClass a -> IO (NSString a) >>. Use them as if they were Objective-C methods in the I<NSString> class. - - =head2 Object Messaging =head3 Sending Messages to Objects @@ -148,11 +152,8 @@ For example, you should pass in C<"initWithURL:byReference:">, and not C<"initWithURLByReference">. - =begin comment -XXX: Put this back in when HOC.Marshal is written ... - =for comment =head3 Generalised Marshaling The C<HOC.Marshal> module provides a function C<< marshal :: a -> @@ -177,6 +178,19 @@ =end comment +=head3 Foundation & AppKit Frameworks + +The Haskell interfaces for the Foundation and AppKit frameworks +(nE<eacute>e Cocoa) are automatically built when you build and +install HOC. To use them, simply write C<import Foundation>, +C<import AppKit> or C<import Cocoa> at the top of your Haskell +module to import the entire framework's class hierarchy and +method definitions into scope. (But, see the section on +L<"Ambiguous Function Names"> to see why some methods are I<not> +imported.) + +To use your own, custom frameworks with HOC, see the chapter on +L<"Accessing Other Frameworks from Haskell">. =head2 Miscellanea @@ -199,8 +213,16 @@ =head3 C<enum> Types +This section is not written yet: please write to the I<hoc-users> +mailing list (see L<http://hoc.sourceforge.net/support.html>) for +assistance or, have a look at the HOC source code yourself. + =head3 C<struct> Types +This section is not written yet: please write to the I<hoc-users> +mailing list (see L<http://hoc.sourceforge.net/support.html>) for +assistance or, have a look at the HOC source code yourself. + =for comment Modeline for vi(m) vi:sw=2 tw=65 |