Re: [Haskell-cafe] FP design
Hello Donn, Wednesday, November 7, 2007, 10:26:20 PM, you wrote: Now it's not like I can't imagine it working better - it may be a little fragile, for one thing - but I have wondered what facilities a Haskell design could have drawn on to de-couple implementation components like that. : http://haskell.org/haskellwiki/Library/Streams also, in Haskell you don't need to worry about data/functions dilemma. we just give names to some parts of program code - no matter which types they will have -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re[2]: [Haskell-cafe] FP design
Hello Levi, Thursday, November 8, 2007, 2:06:14 AM, you wrote: Now I have to learn how to select the appropriate abstractions in Haskell. e.g., selecting between a variant type or type class is often a tricky one for me. that's easy part. i never have need to use type classes in application code, only in libraries. type class allows extending initial behavior in other modules. when you need it - go to use typeclasses -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
I typically start with a list of the types I want, then the minimal list of type signatures. Ideally, it should be possible to write an arbitrarily large set of programs in the given application domain by composing this initial list of functions (so the data type can be specified abstractly, if desired). And if we translate that paragraph into, say, Erlang, what will we get? It seems that we will get a lot of tests instead of types. Or a lot of (pre/post)predicates about values. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] FP design
I have been working on a little Java project lately at work, by way of an introduction to the language, and naturally I often have cause to regret that it isn't Haskell instead. But in the specific matter I'm wrestling with, the Java library's OOP model is, to its credit, allowing me to do some things. I'm using their standard LDAP client library, but swapping in my own function to read X509 certificates for the SSL. Actually, swapping in my own SSL socket implementation, which in my case just calls the standard library SSL socket implementation to do most of the work. Now it's not like I can't imagine it working better - it may be a little fragile, for one thing - but I have wondered what facilities a Haskell design could have drawn on to de-couple implementation components like that. Let's say you download an IMAP mail client library, and look to see if it can operate on a UNIX pipe; on an SSL socket; authenticate with GSSAPI Kerberos 5 -- when none of those things are supported out of the box. (As I have needed, and done, all three of those with the standard Python IMAP library module.) You may also want its I/O operations to integrate with some dispatching core, for a GUI. But of course you also want the basic interface to be simple in this area - the IMAP protocol itself is complicated enough! So I'm the one user in a thousand that will want to provide my own I/O functions, for example. In the old world, I guess I would be looking for some extended API where my I/O functions are parameters to the open or init function, and the IMAP functions take over from there. In a more pure functional oriented model, could it be an extended API that exposes the IMAP functionality as operations on data, and leaves it to me to deal with the I/O? Donn Cave, [EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
On 7 Nov 2007, at 11:26 AM, Donn Cave wrote: I have been working on a little Java project lately at work, by way of an introduction to the language, and naturally I often have cause to regret that it isn't Haskell instead. But in the specific matter I'm wrestling with, the Java library's OOP model is, to its credit, allowing me to do some things. I'm using their standard LDAP client library, but swapping in my own function to read X509 certificates for the SSL. Actually, swapping in my own SSL socket implementation, which in my case just calls the standard library SSL socket implementation to do most of the work. Now it's not like I can't imagine it working better - it may be a little fragile, for one thing - but I have wondered what facilities a Haskell design could have drawn on to de-couple implementation components like that. Let's say you download an IMAP mail client library, and look to see if it can operate on a UNIX pipe; on an SSL socket; authenticate with GSSAPI Kerberos 5 -- when none of those things are supported out of the box. (As I have needed, and done, all three of those with the standard Python IMAP library module.) You may also want its I/O operations to integrate with some dispatching core, for a GUI. But of course you also want the basic interface to be simple in this area - the IMAP protocol itself is complicated enough! So I'm the one user in a thousand that will want to provide my own I/O functions, for example. In the old world, I guess I would be looking for some extended API where my I/O functions are parameters to the open or init function, and the IMAP functions take over from there. In a more pure functional oriented model, could it be an extended API that exposes the IMAP functionality as operations on data, and leaves it to me to deal with the I/O? That would be my ideal: protocol layers implemented as functions over lazy lists. Naturally, those compose very cleanly (at least in a pipeline-like fashion. Combining that with running protocol modules in serial (e.g., using some standard initial authentication protocol, then switching to something else) is a bit more complicated (but certainly very doable)). jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
Bulat Ziganshin wrote: Hello Andrew, Tuesday, November 6, 2007, 10:55:58 PM, you wrote: for me, abstraction is anything that i want to be an abstraction. i just write code in the close-to-natural language and it becomes Haskell program when appropriate syntax applied. Well, in my experience, figuring out just the right abstractions to use i don't think about abstractions, just using top-down approach. for me, FP benefit is that when you see that some two things are similar - you can factor out this similarity. in OOP, you should translate it into some class interface, in Haskell you just define parameterized code/data and it works. selection of good abstractions based on these two criteria: 1) factoring out common parts and 2) existence of natural description of the factored part. if i don't see natural description, i can slightly change the factored part This thread sums up some of my thoughts pretty well. I'm coming from OOP where I was getting comfortable and was confident of spotting appropriate abstractions. Now I have to learn how to select the appropriate abstractions in Haskell. e.g., selecting between a variant type or type class is often a tricky one for me. It is good to hear that people are having success with the code, refactor duplication, repeat process. I have used this in OOP as well and the path it takes is interesting to compare with initial design thoughts. Again, it's just choosing the best way to remove this duplication :) Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
Donn Cave wrote: But in the specific matter I'm wrestling with, the Java library's OOP model is, to its credit, allowing me to do some things. I'm using their standard LDAP client library, but swapping in my own function to read X509 certificates for the SSL. Actually, swapping in my own SSL socket implementation, which in my case just calls the standard library SSL socket implementation to do most of the work. Now it's not like I can't imagine it working better - it may be a little fragile, for one thing - but I have wondered what facilities a Haskell design could have drawn on to de-couple implementation components like that. Let's say you download an IMAP mail client library, and look to see if it can operate on a UNIX pipe; on an SSL socket; authenticate with GSSAPI Kerberos 5 -- when none of those things are supported out of the box. (As I have needed, and done, all three of those with the standard Python IMAP library module.) You may also want its I/O operations to integrate with some dispatching core, for a GUI. But of course you also want the basic interface to be simple in this area - the IMAP protocol itself is complicated enough! I have similar questions about Haskell abstracting away implementations behind interfaces as well. I have become used to an approach where I will not worry about databases/persistence when beginning. I will create an interface to a database layer (e.g., save(object), retrieve(id), findByName(name)) etc., and an implementation that uses in memory collections to begin with. Later I will replace this with database calls. This also helps in my current project as we support multiple databases. If findByName requires different SQL on different databases it's easy to have a different implementation used at run time. How does this type of approach work in Haskell? or what is the Haskell way to achieve this? Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
So I'm the one user in a thousand that will want to provide my own I/O functions, for example. In the old world, I guess I would be looking for some extended API where my I/O functions are parameters to the open or init function, and the IMAP functions take over from there. In a more pure functional oriented model, could it be an extended API that exposes the IMAP functionality as operations on data, and leaves it to me to deal with the I/O? I believe a typeclass could solve this for you. The typeclass member functions serve as your interface definition. For example, say auth was a member function. Then you could implement instances which authorized using NTLM, HTTP Basic, etc. It's similar to how you'd do the same thing in java with interfaces, in fact. Justin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] FP design
levi.stephen wrote: I have similar questions about Haskell abstracting away implementations behind interfaces as well. I have become used to an approach where I will not worry about databases/persistence when beginning. I will create an interface to a database layer (e.g., save(object), retrieve(id), findByName(name)) etc., and an implementation that uses in memory collections to begin with. Later I will replace this with database calls. How does this type of approach work in Haskell? or what is the Haskell way to achieve this? If OO is a good approach for a problem, it's straightforward to model it in haskell. If you plan to access an external DB in any case, then the interface will involve the IO Monad. Something along the lines of: data Object data ID data ObjectStore = ObjectStore { save :: Object - IO ID, retrieve :: IO - IO (Maybe Object), retrieveByName :: String - IO (Maybe Object) } createMemoryStore :: IO ObjectStore connnectExternalStore :: ConnectionParams - IO ObjectStore Tim ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] FP design
levi.stephen wrote: My concern (which may be inexperience ;) ) is with the monads here though. What if I hadn't seen that the IO monad (or any other Monad) was going to be necessary in the type signatures? You'd have some refactoring to do :-) But actually, it's not possible to create an interface that works this way without using some monad, as the interface relies on side-effects. A pure interface would have to look something like: data ObjectStore = ObjectStore { save :: Object - (ID,ObjectStore), retrieve :: ID - Maybe Object, retrieveByName :: Maybe Object } (ie the save method would have to return a new object store). Instead of using IO, you could have parameterised the store over the monad: data ObjectStore m = ObjectStore { save :: Object - m ID, retrieve :: ID - m (Maybe Object), retrieveByName :: String - m (Maybe Object) } but given your planned use, this may well be over-abstraction. Tim ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
Tim Docker wrote: levi.stephen wrote: My concern (which may be inexperience ;) ) is with the monads here though. What if I hadn't seen that the IO monad (or any other Monad) was going to be necessary in the type signatures? You'd have some refactoring to do :-) But actually, it's not possible to create an interface that works this way without using some monad, as the interface relies on side-effects. A pure interface would have to look something like: I agree in this case the monad use is clear. Practically it might a case of if a monad is needed, it's either obvious, or its introduction indicates a refactor being a good thing and will lead to a better design. Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
Tim Docker wrote: levi.stephen wrote: I have similar questions about Haskell abstracting away implementations behind interfaces as well. I have become used to an approach where I will not worry about databases/persistence when beginning. I will create an interface to a database layer (e.g., save(object), retrieve(id), findByName(name)) etc., and an implementation that uses in memory collections to begin with. Later I will replace this with database calls. How does this type of approach work in Haskell? or what is the Haskell way to achieve this? If OO is a good approach for a problem, it's straightforward to model it in haskell. If you plan to access an external DB in any case, then the interface will involve the IO Monad. Something along the lines of: data Object data ID data ObjectStore = ObjectStore { save :: Object - IO ID, retrieve :: IO - IO (Maybe Object), retrieveByName :: String - IO (Maybe Object) } createMemoryStore :: IO ObjectStore connnectExternalStore :: ConnectionParams - IO ObjectStore Tim Thanks for the example. I keep forgetting that I can have use functions like this. I keep having data types made up of just values and/or type classes. I should probably use types like the above more often. My concern (which may be inexperience ;) ) is with the monads here though. What if I hadn't seen that the IO monad (or any other Monad) was going to be necessary in the type signatures? Levi ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
On Wed, 7 Nov 2007, Justin Bailey wrote: So I'm the one user in a thousand that will want to provide my own I/O functions, for example. In the old world, I guess I would be looking for some extended API where my I/O functions are parameters to the open or init function, and the IMAP functions take over from there. In a more pure functional oriented model, could it be an extended API that exposes the IMAP functionality as operations on data, and leaves it to me to deal with the I/O? I believe a typeclass could solve this for you. The typeclass member functions serve as your interface definition. For example, say auth was a member function. Then you could implement instances which authorized using NTLM, HTTP Basic, etc. It's similar to how you'd do the same thing in java with interfaces, in fact. That auth function is not a bad example, because there are a number of cross dependencies along the way to authentication. When you try to design a generic API that will supports all kinds of authentication, you end up with some abominable tangle like SASL, and even then you end up punting on some of them (where does your SSL certificate go?) Some of the underlying protocols involve more than one round trip (Kerberos), others need access to the SSL state, etc. What I'm running up the flagpole here, so to speak, is the notion that if at a larger scale you write your application protocol engine so that it just operates on data and doesn't need to take control over the wire, that might give you a thinner API, and fewer problems to solve via typeclass. Donn Cave, [EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
Levi Stephen wrote: Hi, I'm was wondering how most people work during when designing a functional program. Do you create data structures/types first? Do you work from some type signatures? For example, take a blog. Is the first step likely to be something like: data BlogEntry = BlogEntry { title::String,content::String,comments::[Comment] } type Blog = [BlogEntry] or more likely thinking about what functions will be required: addEntry :: BlogEntry - Blog - Blog displayBlog :: Blog - HTML displayEntry :: BlogEntry - HTML I think you can work either way around, or both, or a mixture. If I had to choose between the two, I would *definitely* choose the second. Writing a program is like defining a custom language. Start by defining your primitives (functions). The data types are just whatever you need to make it work. YMMV :) Jules ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
Levi Stephen wrote: Hi, I'm was wondering how most people work during when designing a functional program. Do you create data structures/types first? Do you work from some type signatures? In *any* programming language, my workflow usually goes like this: 1. Think about it for a minute or two. Try to decide on good abstractions. 2. Start programming it. 3. Realise that my chosen system of abstractions is fundamentally flawed. 4. Delete source code. 5. Think some more. 6. Start coding again using new plan. 7. Iterate as required. I'm not sure whether you can properly call that design though... more like iterative prototyping. ;-) It used to be easier with OOP. I'm still not quite sure how to pick the best possible abstractions in an FP context... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re[2]: [Haskell-cafe] FP design
Hello Andrew, Tuesday, November 6, 2007, 9:34:34 PM, you wrote: It used to be easier with OOP. I'm still not quite sure how to pick the best possible abstractions in an FP context... for me, abstraction is anything that i want to be an abstraction. i just write code in the close-to-natural language and it becomes Haskell program when appropriate syntax applied. say, i want to display archive listing. i write: dir - readDir archive listing = map listfile dir print$ [header]++listing++[footer] then i write definitions of readDir, listfile and so on in the same manner -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
On Tue, 2007-11-06 at 10:32 +1030, Levi Stephen wrote: Hi, I'm was wondering how most people work during when designing a functional program. Do you create data structures/types first? Do you work from some type signatures? As others have mentioned: both. But there's a third thing that you can do, other than start implementing: think about the laws/properties that should hold. That's not always simple, in fact, it rarely is. But it helps you get one step closer to what you need to implement. If you can find useful properties, though, you get lots of test-cases for free by formulating and testing them using QuickCheck. Then, when implementing, you probably realize that you might need some more combinators. I usually then stop and implement the combinator first, test it and continue. Some other guidelines I recommend: * Try not to be too abstract in the first place. Try implementing a specialized version first, and then see how you can abstract it, once you implemented all facets. Sometimes, you need to add some instance constraints, but the compiler will tell you where. * Test early and often. Note that in Haskell you can get the compiler to typecheck successfully by adding dummy-definitions using _ and undefined. E.g.: foo :: A - B - C foo _ _ = undefined * Define abstract types, or at least type synonyms. It's so easy to define new abstract types in Haskell, that you should do it often. This makes it much easier to later choose the proper data structure, once you know what details you need. Also, it's implicit documentation, compare type Author = String; type Title = String addPost :: Author - Title - String - Blog - Blog and addPost :: String - String - String - Blog - Blog * Think about complexity of your primitives. This is hard to fix later, so it should be taken into account early on. Of course, there's sometimes a fine line between mature and premature optimizations. * As Don often says, try to keep things pure wherever possible. It will make your code so much more compositional, easier to test and correct. There's more, but I'll stop here for now... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
Bulat Ziganshin wrote: Hello Andrew, Tuesday, November 6, 2007, 9:34:34 PM, you wrote: It used to be easier with OOP. I'm still not quite sure how to pick the best possible abstractions in an FP context... for me, abstraction is anything that i want to be an abstraction. i just write code in the close-to-natural language and it becomes Haskell program when appropriate syntax applied. Well, in my experience, figuring out just the right abstractions to use is the difference between a huge pile of code that really doesn't quite work right, and a much smaller, simpler, more capable program. Unfortunately, figuring out the best way to divide up a given problem usually requires a lot of trial and error. (I was just starting to get good at it in OOP... now I'm back at the bottom. Heh!) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re[2]: [Haskell-cafe] FP design
Hello Andrew, Tuesday, November 6, 2007, 10:55:58 PM, you wrote: for me, abstraction is anything that i want to be an abstraction. i just write code in the close-to-natural language and it becomes Haskell program when appropriate syntax applied. Well, in my experience, figuring out just the right abstractions to use i don't think about abstractions, just using top-down approach. for me, FP benefit is that when you see that some two things are similar - you can factor out this similarity. in OOP, you should translate it into some class interface, in Haskell you just define parameterized code/data and it works. selection of good abstractions based on these two criteria: 1) factoring out common parts and 2) existence of natural description of the factored part. if i don't see natural description, i can slightly change the factored part -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] FP design
Hi, I'm was wondering how most people work during when designing a functional program. Do you create data structures/types first? Do you work from some type signatures? For example, take a blog. Is the first step likely to be something like: data BlogEntry = BlogEntry { title::String,content::String,comments::[Comment] } type Blog = [BlogEntry] or more likely thinking about what functions will be required: addEntry :: BlogEntry - Blog - Blog displayBlog :: Blog - HTML displayEntry :: BlogEntry - HTML I'm trying to get my brain out of thinking OO thinking more functionally. Thanks, Levi lstephen.wordpress.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
Hello Levi, Tuesday, November 6, 2007, 3:02:49 AM, you wrote: I'm was wondering how most people work during when designing a functional program. Do you create data structures/types first? Do you work from some type signatures? not first nor second. i write function bodies, then declare appropriate data types when required and don't write function types at all from my POV, FP allows to concentrate on the algorithms and mostly ignore all auxiliary definitions -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
On 11/5/07, Levi Stephen [EMAIL PROTECTED] wrote: Hi, I'm was wondering how most people work during when designing a functional program. Do you create data structures/types first? Do you work from some type signatures? For example, take a blog. Is the first step likely to be something like: data BlogEntry = BlogEntry { title::String,content::String,comments::[Comment] } type Blog = [BlogEntry] or more likely thinking about what functions will be required: addEntry :: BlogEntry - Blog - Blog displayBlog :: Blog - HTML displayEntry :: BlogEntry - HTML I don't know how you can do one without the other. I would probably start in a case like this by writing down a few basic types, then trying to start to write down the function type signatures, which will probably point to more types that need to be defined, iterating until I reach a fixed point. I can't write type signatures unless I know what the types are. But I don't know what the types should look like unless I know what the interface should look like, either. One thing that's for sure, though -- I always write type signatures for top-level definitions. I can't think straight unless I write the type signature before writing the code. Cheers, Tim -- Tim Chevalier * catamorphism.org * Often in error, never in doubt Thus spake the Master Programmer: When you have learned to snatch the error code from the trap frame, it will be time for you to leave.--J. Geoffrey ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FP design
On Tue, 2007-11-06 at 10:32 +1030, Levi Stephen wrote: Hi, I'm was wondering how most people work during when designing a functional program. Do you create data structures/types first? Do you work from some type signatures? For example, take a blog. Is the first step likely to be something like: data BlogEntry = BlogEntry { title::String,content::String,comments::[Comment] } type Blog = [BlogEntry] or more likely thinking about what functions will be required: addEntry :: BlogEntry - Blog - Blog displayBlog :: Blog - HTML displayEntry :: BlogEntry - HTML I'm trying to get my brain out of thinking OO thinking more functionally. I typically start with a list of the types I want, then the minimal list of type signatures. Ideally, it should be possible to write an arbitrarily large set of programs in the given application domain by composing this initial list of functions (so the data type can be specified abstractly, if desired). Then I define the bodies of the types, then I find out that I can't define the functions elegantly, so I start over from the top. Once my function definitions are natural, I know I'm done, so I can start writing derived functions (key insight: most functions in FP don't need access to the representation of your data types. This is the counter-part, if you will, of encapsulation in OO: well-encapsulated types are those where most code can be written by composing a short list of primitives with direct access to the type.) jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe