Analysis and Design for Functional Programming [closed]
Asked Answered
V

2

9

How do you deal with analysis and design phases when you plan to develop a system using a functional programming language like Haskell?

My background is in imperative/object-oriented programming languages, and therefore, I am used to use case analysis and the use of UML to document the design of program. But the thing is that UML is inherently related to the object-oriented way of doing software.

And I am intrigued about what would be the best way to develop documentation and define software designs for a system that is going to be developed using functional programming.

  • Would you still use use case analysis or perhaps structured analysis and design instead?
  • How do software architects define the high-level design of the system so that developers follow it?
  • What do you show to you clients or to new developers when you are supposed to present a design of the solution?
  • How do you document a picture of the whole thing without having first to write it all?
  • Is there anything comparable to UML in the functional world?
Verify answered 12/4, 2012 at 17:57 Comment(2)
possible duplicate of Is there a software-engineering methodology for functional programming?Sammysamoan
Just touching on one thing you mentioned, haddock is the recommended documentation form. Wise creation of modules, functions, and packages usually makes haddock sufficient to document code sufficiently (plus cabal package descriptions).Rockwell
R
1

I'm no professional but I'll try my hand at answering some of these questions.

Would you still use use case analysis [?]

I don't see why not. Gather use cases, and design a module API that you wish to expose that satisfies the use cases. Determine whether the use cases call for a typeclass, or for just plain functions.

or perhaps structured analysis and design instead?

I'm unfamiliar with that approach, but from what I gather from the wiki article, it looks like it would work just fine.

How do software architects define the high-level design of the system so that developers follow it?

I would assume that they specify a module and the types that each part of the module should have. Again, I am not a professional, so I'm not really sure what is done in practice.

What do you show to you clients or to new developers when you are supposed to present a design of the solution?

You show the clients something that will make sense to them. If your client is savvy enough, just show them the type signatures and explain the important functions. If they are less savvy, then draw pretty pictures, or whatever you have to do. OOP makes comparisons with real world objects, while FP makes comparisons with...well...functions. The typical way to illustrate a function to newbies is to portray it as a machine where you put certain things in, and then other things come out.

How do you document a picture of the whole thing without having first to write it all?

A "picture"? Just defining the type signature for the important functions, and then leave the implementation as undefined. There's a package out there somewhere that gives you better stubs that will remind you at compile time which parts you still need to implement.

Is there anything comparable to UML in the functional world?

Um...no?

Rockwell answered 12/4, 2012 at 23:25 Comment(0)
P
-7

Let's examine this claim:

UML is inherently related to the object-oriented way of doing software.

First of all, this is not really true. You can still model interactions, use-cases, states, and data models in UML whatever the implementation is to be.

Second of all, Haskell's type classes are a form of object-orientation: they provide polymorphic dispatch on the type of their arguments (which allows different function implementations that use the data that exist in that type).

So, yes, if you really want to keep using UML, go ahead.

Permanence answered 12/4, 2012 at 18:2 Comment(18)
Haskell's type classes are not a form of object-orientation. They are a form of ad-hoc polymorphism, which you typically also get from object systems. But they do not couple data and methods, which is the hallmark of object-orientation.Sammysamoan
@Sammysamoan They do in fact couple data and methods - the type of the data determines which function (or which part of the function definition if you want to view it that way) is called.Permanence
that couples the type of the data and methods! haskell.org/haskellwiki/OOP_vs_type_classesSammysamoan
@Sammysamoan is right; Haskell typeclasses are much closer to OOP interfaces than OOP classes, but even that analogy isn't perfect. In fact, the closest thing to OOP classes in Haskell are simply data types containing functions and monadic actions.Postdiluvian
@Sammysamoan Yes, and that is characteristic of object oriented languages. Only a minority associate operations with instances at all; in even fewer can that be described as the normal operation of the OO system.Permanence
@Sammysamoan I dont think this is true (although it is an acceptable "lie to children"). If you dont think about the constraint system, typeclasses are just a slightly restricted object system. In that typeclasses have 1. subtyping 2. implicit self reference 3. replaceable self reference (aka inheritance). A typeclass is just a (parameterized) abstract class in oop while an instance is just an object that inherits from that abstract class. With GHC 7.4 and some trickery involving newtype, unsafeCoerce and implicit parameters this correspondence becomes complete.Grume
I also think that "couple data and methods" is really independent from OO. Consider Go as the example of a language where methods are separate from structs, yet it is very OOP.Grume
On the other hand, the naive view that typeclasses are equivalent to interfaces and that datatypes in Haskell are equivalent to classes in OOP that implement those interfaces is just wrong. The typeclass system is a layer used for defining classes (in the mathematical sense, aka predicates) over Haskell types. It just happens to be an Object Oriented layer to for defining predicates over Haskell types.Grume
@PhilipJF My answer in no way relies on OO being able to do everything that Haskell type classes can do. It relies on the Haskell type class system being able to do everything that OO can.Permanence
@PhilipJF Don't know why I'm responding to this nonsense, but typeclasses don't have subtyping, don't have implicit self reference, and don't have inheritance. The "Haskell's Overlooked Object System" paper has a good discussion of why typeclasses don't do the job (and hence what it proposes instead), and I think the O'Haskell paper also motivate the differences quite well. Anyway, implicit parameters are not idiomatic Haskell these days, and unlikely to make it into a standard, and once you start to involve unsafeCoerce then you're clearly off the reservation.Sammysamoan
@Sammysamoan I'm not sure what either of those papers have to do with my claim. The class per class encoding is clumsy, I agree. My point is more subtle. Typeclasses in Haskell are classes over types. We are all constructivist here, so for us to suppose a type is a member of a typeclass requires some sort of "evidence object". Further, the language provides an automatic theorem proving system in the form of inference and global instances. My claim is only that the proof language for this logic is OO, and it is helpful for reasoning about Haskell to be aware of this fact.Grume
The "evidence type" for membership in Ord is a subtype of the evidence type for membership in Eq. Implicit this references and inheritance are what let you declare m >> k = m >>= \_ -> k" in the definition of Monad`. To simulate this behavior with records requires finding a fix-point (as pointed out by Oleg), which should clue you in something is up. The reason this shouldn't be surprising is that typeclasses sit on the other-side of the "expresion problem" from Abstract Data Types. From William Cooks work we know that means they are probably objects.Grume
Obviously this object system is a restricted one, but you just need to look at Bruno Oliveira's work to know that is a non-essential aspect (see Scala's implicits). My point about unsafeCoerce is that with some extensions and unsafe features you can actually get your hands on the Objects that bare witness to type-class membership , and using implicit parameters you can construct arbitrary such instances at runtime (although it relies on the compiler not obeying its documentation).Grume
@PhilipJF the "evidence type" for membership in Ord (dictionary, I suppose you mean) isn't a subtype of the evidence type for membership in Eq. It's just that Ord membership implies Eq membership. An ord instance can't "override" Eq methods. I have no idea what you're getting at with the monad example -- yes if you encode monads with objects, then the encoding is object-y, but that's because you chose an object-y encoding to begin with! Anyway, this "evidence type" doesn't always exist. Other implementations of Haskell, such as JHC, show you can go very far without a dictionary encoding.Sammysamoan
@Sammysamoan A proof of membership in Ord is a proof of membership in Eq. "is a" is the same thing as subtype. The Monad example is about inheritance (not subtyping, they are separate) since unless a Monad instance overrides the default definition of >> it inherits a general one, but this general one uses >>= which is defined virtually. This is what I was talking about in terms of "implicit this parameter" and inheritance. The point that you dont have direct access to this object system and that it isn't always implemented directly, doesn't really matter. It explains the semantics.Grume
But you can explain the semantics without an object system too. Does the fact that I can explain counting with pebbles mean that naturals are a kind of collection of pebbles?Sammysamoan
@Sammysamoan An object system is anything that meets certain criteria. You cannot say the same of a collection of pebbles.Permanence
that is a good point. I find that thinking about typeclasses as objects plus a Prolog like theorem prover (where every rule begins with a cute) makes it easier to reason about something rather complicated, and gives me access to a body of literatures and design principles that apply to my problem. Thinking about C++ templates as a functional language sort of like Haskell makes them easier to reason about also. I generally try to understand the weird edges of mathematical systems by describing them in terms of axioms I already know. You dont need ring theory to explain integers.Grume

© 2022 - 2024 — McMap. All rights reserved.