Large-scale design in Haskell? [closed] - haskell

Closed. This question needs to be more focused. It is not currently accepting answers.
Closed 6 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
What is a good way to design/structure large functional programs, especially in Haskell?
I've been through a bunch of the tutorials (Write Yourself a Scheme being my favorite, with Real World Haskell a close second) - but most of the programs are relatively small, and single-purpose. Additionally, I don't consider some of them to be particularly elegant (for example, the vast lookup tables in WYAS).
I'm now wanting to write larger programs, with more moving parts - acquiring data from a variety of different sources, cleaning it, processing it in various ways, displaying it in user interfaces, persisting it, communicating over networks, etc. How could one best structure such code to be legible, maintainable, and adaptable to changing requirements?
There is quite a large literature addressing these questions for large object-oriented imperative programs. Ideas like MVC, design patterns, etc. are decent prescriptions for realizing broad goals like separation of concerns and reusability in an OO style. Additionally, newer imperative languages lend themselves to a 'design as you grow' style of refactoring to which, in my novice opinion, Haskell appears less well-suited.
Is there an equivalent literature for Haskell? How is the zoo of exotic control structures available in functional programming (monads, arrows, applicative, etc.) best employed for this purpose? What best practices could you recommend?
Thanks!
EDIT (this is a follow-up to Don Stewart's answer):
#dons mentioned: "Monads capture key architectural designs in types."
I guess my question is: how should one think about key architectural designs in a pure functional language?
Consider the example of several data streams, and several processing steps. I can write modular parsers for the data streams to a set of data structures, and I can implement each processing step as a pure function. The processing steps required for one piece of data will depend on its value and others'. Some of the steps should be followed by side-effects like GUI updates or database queries.
What's the 'Right' way to tie the data and the parsing steps in a nice way? One could write a big function which does the right thing for the various data types. Or one could use a monad to keep track of what's been processed so far and have each processing step get whatever it needs next from the monad state. Or one could write largely separate programs and send messages around (I don't much like this option).
The slides he linked have a Things we Need bullet: "Idioms for mapping design onto
types/functions/classes/monads". What are the idioms? :)

I talk a bit about this in Engineering Large Projects in Haskell and in the Design and Implementation of XMonad. Engineering in the large is about managing complexity. The primary code structuring mechanisms in Haskell for managing complexity are:
The type system
Use the type system to enforce abstractions, simplifying interactions.
Enforce key invariants via types
(e.g. that certain values cannot escape some scope)
That certain code does no IO, does not touch the disk
Enforce safety: checked exceptions (Maybe/Either), avoid mixing concepts (Word, Int, Address)
Good data structures (like zippers) can make some classes of testing needless, as they rule out e.g. out of bounds errors statically.
The profiler
Provide objective evidence of your program's heap and time profiles.
Heap profiling, in particular, is the best way to ensure no unnecessary memory use.
Purity
Reduce complexity dramatically by removing state. Purely functional code scales, because it is compositional. All you need is the type to determine how to use some code -- it won't mysteriously break when you change some other part of the program.
Use lots of "model/view/controller" style programming: parse external data as soon as possible into purely functional data structures, operate on those structures, then once all work is done, render/flush/serialize out. Keeps most of your code pure
Testing
QuickCheck + Haskell Code Coverage, to ensure you are testing the things you can't check with types.
GHC + RTS is great for seeing if you're spending too much time doing GC.
QuickCheck can also help you identify clean, orthogonal APIs for your modules. If the properties of your code are difficult to state, they're probably too complex. Keep refactoring until you have a clean set of properties that can test your code, that compose well. Then the code is probably well designed too.
Monads for Structuring
Monads capture key architectural designs in types (this code accesses hardware, this code is a single-user session, etc.)
E.g. the X monad in xmonad, captures precisely the design for what state is visible to what components of the system.
Type classes and existential types
Use type classes to provide abstraction: hide implementations behind polymorphic interfaces.
Concurrency and parallelism
Sneak par into your program to beat the competition with easy, composable parallelism.
Refactor
You can refactor in Haskell a lot. The types ensure your large scale changes will be safe, if you're using types wisely. This will help your codebase scale. Make sure that your refactorings will cause type errors until complete.
Use the FFI wisely
The FFI makes it easier to play with foreign code, but that foreign code can be dangerous.
Be very careful in assumptions about the shape of data returned.
Meta programming
A bit of Template Haskell or generics can remove boilerplate.
Packaging and distribution
Use Cabal. Don't roll your own build system. (EDIT: Actually you probably want to use Stack now for getting started.).
Use Haddock for good API docs
Tools like graphmod can show your module structures.
Rely on the Haskell Platform versions of libraries and tools, if at all possible. It is a stable base. (EDIT: Again, these days you likely want to use Stack for getting a stable base up and running.)
Warnings
Use -Wall to keep your code clean of smells. You might also look at Agda, Isabelle or Catch for more assurance. For lint-like checking, see the great hlint, which will suggest improvements.
With all these tools you can keep a handle on complexity, removing as many interactions between components as possible. Ideally, you have a very large base of pure code, which is really easy to maintain, since it is compositional. That's not always possible, but it is worth aiming for.
In general: decompose the logical units of your system into the smallest referentially transparent components possible, then implement them in modules. Global or local environments for sets of components (or inside components) might be mapped to monads. Use algebraic data types to describe core data structures. Share those definitions widely.

Don gave you most of the details above, but here's my two cents from doing really nitty-gritty stateful programs like system daemons in Haskell.
In the end, you live in a monad transformer stack. At the bottom is IO. Above that, every major module (in the abstract sense, not the module-in-a-file sense) maps its necessary state into a layer in that stack. So if you have your database connection code hidden in a module, you write it all to be over a type MonadReader Connection m => ... -> m ... and then your database functions can always get their connection without functions from other modules having to be aware of its existence. You might end up with one layer carrying your database connection, another your configuration, a third your various semaphores and mvars for the resolution of parallelism and synchronization, another your log file handles, etc.
Figure out your error handling first. The greatest weakness at the moment for Haskell in larger systems is the plethora of error handling methods, including lousy ones like Maybe (which is wrong because you can't return any information on what went wrong; always use Either instead of Maybe unless you really just mean missing values). Figure out how you're going to do it first, and set up adapters from the various error handling mechanisms your libraries and other code uses into your final one. This will save you a world of grief later.
Addendum (extracted from comments; thanks to Lii & liminalisht) —
more discussion about different ways to slice a large program into monads in a stack:
Ben Kolera gives a great practical intro to this topic, and Brian Hurt discusses solutions to the problem of lifting monadic actions into your custom monad. George Wilson shows how to use mtl to write code that works with any monad that implements the required typeclasses, rather than your custom monad kind. Carlo Hamalainen has written some short, useful notes summarizing George's talk.

Designing large programs in Haskell is not that different from doing it in other languages.
Programming in the large is about breaking your problem into manageable pieces, and how to fit those together; the implementation language is less important.
That said, in a large design it's nice to try and leverage the type system to make sure you can only fit your pieces together in a way that is correct. This might involve newtype or phantom types to make things that appear to have the same type be different.
When it comes to refactoring the code as you go along, purity is a great boon, so try to keep as much of the code as possible pure. Pure code is easy to refactor, because it has no hidden interaction with other parts of your program.

I did learn structured functional programming the first time with this book.
It may not be exactly what you are looking for, but for beginners in functional programming, this may be one of the best first steps to learn to structure functional programs - independant of the scale. On all abstraction levels, the design should always have clearly arranged structures.
The Craft of Functional Programming
http://www.cs.kent.ac.uk/people/staff/sjt/craft2e/

I'm currently writing a book with the title "Functional Design and Architecture". It provides you with a complete set of techniques how to build a big application using pure functional approach. It describes many functional patterns and ideas while building an SCADA-like application 'Andromeda' for controlling spaceships from scratch. My primary language is Haskell. The book covers:
Approaches to architecture modelling using diagrams;
Requirements analysis;
Embedded DSL domain modelling;
External DSL design and implementation;
Monads as subsystems with effects;
Free monads as functional interfaces;
Arrowised eDSLs;
Inversion of Control using Free monadic eDSLs;
Software Transactional Memory;
Lenses;
State, Reader, Writer, RWS, ST monads;
Impure state: IORef, MVar, STM;
Multithreading and concurrent domain modelling;
GUI;
Applicability of mainstream techniques and approaches such as UML, SOLID, GRASP;
Interaction with impure subsystems.
You may get familiar with the code for the book here, and the 'Andromeda' project code.
I expect to finish this book at the end of 2017. Until that happens, you may read my article "Design and Architecture in Functional Programming" (Rus) here.
UPDATE
I shared my book online (first 5 chapters). See post on Reddit

Gabriel's blog post Scalable program architectures might be worth a mention.
Haskell design patterns differ from mainstream design patterns in one
important way:
Conventional architecture: Combine a several components together of
type A to generate a "network" or "topology" of type B
Haskell architecture: Combine several components together of type A to
generate a new component of the same type A, indistinguishable in
character from its substituent parts
It often strikes me that an apparently elegant architecture often tends to fall out of libraries that exhibit this nice sense of homogeneity, in a bottom-up sort of way. In Haskell this is especially apparent - patterns that would traditionally be considered "top-down architecture" tend to be captured in libraries like mvc, Netwire and Cloud Haskell. That is to say, I hope this answer will not be interpreted as an attempt replace any of the others in this thread, just that structural choices can and should ideally be abstracted away in libraries by domain experts. The real difficulty in building large systems, in my opinion, is evaluating these libraries on their architectural "goodness" versus all of your pragmatic concerns.
As liminalisht mentions in the comments, The category design pattern is another post by Gabriel on the topic, in a similar vein.

I have found the paper "Teaching Software Architecture Using Haskell" (pdf) by Alejandro Serrano useful for thinking about large-scale structure in Haskell.

Perhaps you have to go an step back and think of how to translate the description of the problem to a design in the first place. Since Haskell is so high level, it can capture the description of the problem in the form of data structures , the actions as procedures and the pure transformation as functions. Then you have a design. The development start when you compile this code and find concrete errors about missing fields, missing instances and missing monadic transformers in your code, because for example you perform a database Access from a library that need a certain state monad within an IO procedure. And voila, there is the program. The compiler feed your mental sketches and gives coherence to the design and the development.
In such a way you benefit from the help of Haskell since the beginning, and the coding is natural. I would not care to do something "functional" or "pure" or enough general if what you have in mind is a concrete ordinary problem. I think that over-engineering is the most dangerous thing in IT. Things are different when the problem is to create a library that abstract a set of related problems.

Related

What's the status of current Functional Reactive Programming implementations?

I'm trying to visualize some simple automatic physical systems (such things as pendulum, robot arms,etc.) in Haskell.
Often those systems can be described by equations like
df/dt = c*f(t) + u(t)
where u(t) represents some kind of 'intelligent control'. Those systems look to fit very nicely in the Functional Reactive Programming paradigm.
So I grabbed the book "The Haskell School of Expression" by Paul Hudak,
and found that the domain specific language "FAL" (for Functional Animation Language) presented there actually works quite pleasently for my simple toy systems (although some functions, notably integrate, seemed to be a bit too lazy for an efficient use, but easily fixable).
My question is, what's the more mature, up-to-date, well-maintained, performance-tuned alternative for more advanced, or even practical applications today?
This wiki page lists several options for Haskell, but I'm not clear about the following respects:
The status of "reactive", the project from Conal Eliott who is (as I understand it) one of the inventers of this programming paradigm, looks a bit stale. I love his code, but maybe I should try other more up-to-date alternatives? What's the primary difference between them, in terms of syntax/performance/runtime-stability?
To quote from a survey in 2011, Section 6, "... FRP implementations are still not efficient enough or predictable enough in performance to be used effectively in domains which require latency guarantees ...". Alghough the survey suggests some interesting possible optimizations, given the fact that FRP is there for more than 15 years, I get the impression that this performance problem might be something very or even inherently difficult to solve at least within a few years. Is this true?
The same author of the survey talks about "time leaks" in his blog. Is the problem unique to FRP, or something we are generally having when programming in a pure, non-strict language? Have you ever found it just too difficult to stabilize an FRP-based system over time, if not performant enough?
Is this still a research level project? Are the people like plant engineers, robotics engineers, financial engineers, etc. actually using them (in whaterver language that suits their needs)?
Although I personally prefer a Haskell implementation, I'm open to other suggestions. For example, it would be particularly fun to have an Erlang implementation --- it would then be very easy to have an intelligent, adaptive, self-learning server process!
Right now there are mainly two practical Haskell libraries out there for functional reactive programming. Both are maintained by single persons, but are receiving code contributions from other Haskell programmers as well:
Netwire focusses on efficiency, flexibility and predictability. It has its own event paradigm and can be used in areas where traditional FRP does not work, including network services and complex simulations. Style: applicative and/or arrowized. Initial author and maintainer: Ertugrul Söylemez (this is me).
reactive-banana builds on the traditional FRP paradigm. While it is practical to use it also serves as ground for classic FRP research. Its main focus is on user interfaces and there is a ready-made interface to wx. Style: applicative. Initial author and maintainer: Heinrich Apfelmus.
You should try both of them, but depending on your application you will likely find one or the other to be a better fit.
For games, networking, robot control and simulations you will find Netwire to be useful. It comes with ready-made wires for those applications, including various useful differentials, integrals and lots of functionality for transparent event handling. For a tutorial visit the documentation of the Control.Wire module on the page I linked.
For graphical user interfaces currently your best choice is reactive-banana. It already has a wx interface (as a separate library reactive-banana-wx) and Heinrich blogs a lot about FRP in this context including code samples.
To answer your other questions: FRP isn't suitable in scenarios where you need real-time predictability. This is largely due to Haskell, but unfortunately FRP is difficult to realize in lower level languages. As soon as Haskell itself becomes real-time-ready, FRP will get there, too. Conceptually Netwire is ready for real-time applications.
Time leaks aren't really a problem anymore, because they are largely related to the monadic framework. Practical FRP implementations simply don't offer a monadic interface. Yampa has started this and Netwire and reactive-banana both build on that.
I know of no commercial or otherwise large scale projects using FRP right now. The libraries are ready, but I think the people aren't – yet.
Although there are some good answers already, I'm going to attempt to answer your specific questions.
reactive is not usable for serious projects, due to time leak problems. (see #3). The current library with the most similar design is reactive-banana, which was developed with reactive as an inspiration, and in discussion with Conal Elliott.
Although Haskell itself is inappropriate for hard real-time applications, it is possible to use Haskell for soft realtime applications in some cases. I'm not familiar with current research, but I don't believe this is an insurmountable problem. I suspect that either systems like Yampa, or code generation systems like Atom, are possibly the best approach to solving this.
A "time leak" is a problem specific to switchable FRP. The leak occurs when a system is unable to free old objects because it may need them if a switch were to occur at some point in the future. In addition to a memory leak (which can be quite severe), another consequence is that, when the switch occurs, the system must pause while the chain of old objects is traversed to generate current state.
Non-switchable frp libraries such as Yampa and older versions of reactive-banana don't suffer from time leaks. Switchable frp libraries generally employ one of two schemes: either they have a special "creation monad" in which FRP values are created, or they use an "aging" type parameter to limit the contexts in which switches can occur. elerea (and possibly netwire?) use the former, whereas recent reactive-banana and grapefruit use the latter.
By "switchable frp", I mean one which implements Conal's function switcher :: Behavior a -> Event (Behavior a) -> Behavior a, or identical semantics. This means that the shape of the network can dynamically switch as it's run.
This doesn't really contradict #ertes's statement about monadic interfaces: it turns out that providing a Monad instance for an Event makes time leaks possible, and with either of the above approaches it's no longer possible to define the equivalent Monad instances.
Finally, although there's still a lot of work remaining to be done with FRP, I think some of the newer platforms (reactive-banana, elerea, netwire) are stable and mature enough that you can build reliable code from them. But you may need to spend a lot of time learning the ins and outs in order to understand how to get good performance.
I'm going to list a couple of items in the Mono and .Net space and one from the Haskell space that I found not too long ago. I'll start with Haskell.
Elm - link
Its description as per its site:
Elm aims to make front-end web development more pleasant. It
introduces a new approach to GUI programming that corrects the
systemic problems of HTML, CSS, and JavaScript. Elm allows you to
quickly and easily work with visual layout, use the canvas, manage
complicated user input, and escape from callback hell.
It has its own variant of FRP. From playing with its examples it seems pretty mature.
Reactive Extensions - link
Description from its front page:
The Reactive Extensions (Rx) is a library for composing asynchronous
and event-based programs using observable sequences and LINQ-style
query operators. Using Rx, developers represent asynchronous data
streams with Observables, query asynchronous data streams using LINQ
operators, and parameterize the concurrency in the asynchronous data
streams using Schedulers. Simply put, Rx = Observables + LINQ +
Schedulers.
Reactive Extensions comes from MSFT and implements many excellent operators that simplify handling events. It was open sourced just a couple of days ago. It's very mature and used in production; in my opinion it would have been a nicer API for the Windows 8 APIs than the TPL-library provides; because observables can be both hot and cold and retried/merged etc, while tasks always represent hot or done computations that are either running, faulted or completed.
I've written server-side code using Rx for asynchronocity, but I must admit that writing functionally in C# can be a bit annoying. F# has a couple of wrappers, but it's been hard to track the API development, because the group is relatively closed and isn't promoted by MSFT like other projects are.
Its open sourcing came with the open sourcing of its IL-to-JS compiler, so it could probably work well with JavaScript or Elm.
You could probably bind F#/C#/JS/Haskell together very nicely using a message broker, like RabbitMQ and SocksJS.
Bling UI Toolkit - link
Description from its front page:
Bling is a C#-based library for easily programming images, animations,
interactions, and visualizations on Microsoft's WPF/.NET. Bling is
oriented towards design technologists, i.e., designers who sometimes
program, to aid in the rapid prototyping of rich UI design ideas.
Students, artists, researchers, and hobbyists will also find Bling
useful as a tool for quickly expressing ideas or visualizations.
Bling's APIs and constructs are optimized for the fast programming of
throw away code as opposed to the careful programming of production
code.
Complimentary LtU-article.
I've tested this, but not worked with it for a client project. It looks awesome, has nice C# operator overloading that form the bindings between values. It uses dependency properties in WPF/SL/(WinRT) as event sources. Its 3D animations work well on reasonable hardware. I would use this if I end up on a project in need for visualizations; probably porting it to Windows 8.
ReactiveUI - link
Paul Betts, previously at MSFT, now at Github, wrote that framework. I've worked with it pretty extensively and like the model. It's more decoupled than Blink (by its nature from using Rx and its abstractions) - making it easier to unit test code using it. The github git client for Windows is written in this.
Comments
The reactive model is performant enough for most performance-demanding applications. If you are thinking of hard real-time, I'd wager that most GC-languages have problems. Rx, ReactiveUI create some amount of small object that need to be GCed, because that's how subscriptions are created/disposed and intermediate values are progressed in the reactive "monad" of callbacks. In general on .Net I prefer reactive programming over task-based programming because callbacks are static (known at compile time, no allocation) while tasks are dynamically allocated (not known, all calls need an instance, garbage created) - and lambdas compile into compiler-generated classes.
Obviously C# and F# are strictly evaluated, so time-leak isn't a problem here. Same for JS. It can be a problem with replayable or cached observables though.

Why is the "Dynamic" part of Dynamic languages so good?

Jon Skeet posted this blog post, in which he states that he is going to be asking why the dynamic part of languages are so good. So i thought i'd preemptively ask on his behalf: What makes them so good?
The two fundamentally different approaches to types in programming languages are static types and dynamic types. They enable very different programming paradigms and they each have their own benefits and drawbacks.
I'd highly recommend Chris Smith's excellent article What to Know Before Debating Type Systems for more background on the subject.
From that article:
A static type system is a mechanism by which a compiler examines source code and assigns labels (called "types") to pieces of the syntax, and then uses them to infer something about the program's behavior. A dynamic type system is a mechanism by which a compiler generates code to keep track of the sort of data (coincidentally, also called its "type") used by the program. The use of the same word "type" in each of these two systems is, of course, not really entirely coincidental; yet it is best understood as having a sort of weak historical significance. Great confusion results from trying to find a world view in which "type" really means the same thing in both systems. It doesn't. The better way to approach the issue is to recognize that:
Much of the time, programmers are trying to solve the same problem with
static and dynamic types.
Nevertheless, static types are not limited to problems solved by dynamic
types.
Nor are dynamic types limited to problems that can be solved with
static types.
At their core, these two techniques are not the same thing at all.
The main thing is that you avoid a lot of redundancy that comes from making the programmer "declare" this, that, and the other. A similar advantage could be obtained through type inferencing (boo does that, for example) but not quite as cheaply and flexibly. As I wrote in the past...:
complete type checking or inference
requires analysis of the whole
program, which may be quite
impractical -- and stops what Van Roy
and Haridi, in their masterpiece
"Concepts, Techniques and Models of
Computer Programming", call "totally
open programming". Quoting a post of
mine from 2004: """ I love the
explanations of Van Roy and Haridi, p.
104-106 of their book, though I may or
may not agree with their conclusions
(which are basically that the
intrinsic difference is tiny -- they
point to Oz and Alice as interoperable
languages without and with static
typing, respectively), all the points
they make are good. Most importantly,
I believe, the way dynamic typing
allows real modularity (harder with
static typing, since type discipline
must be enforced across module
boundaries), and "exploratory
computing in a computation model that
integrates several programming
paradigms".
"Dynamic typing is recommended", they
conclude, "when programs must be as
flexible as possible". I recommend
reading the Agile Manifesto to
understand why maximal flexibility is
crucial in most real-world
application programming -- and
therefore why, in said real world
rather than in the more academic
circles Dr. Van Roy and Dr. Hadidi
move in, dynamic typing is generally
preferable, and not such a tiny issue
as they make the difference to be.
Still, they at least show more
awareness of the issues, in devoting 3
excellent pages of discussion about
it, pros and cons, than almost any
other book I've seen -- most books
have clearly delineated and preformed
precedence one way or the other, so
the discussion is rarely as balanced
as that;).
I'd start with recommending reading Steve Yegge's post on Is Weak Typing Strong Enough, then his post on Dynamic Languages Strike Back. That ought to at least get you started!
Let's do a few advantage/disadvantage comparisons:
Dynamic Languages:
Type decisions can be changed with minimal code impact.
Code can be written/compiled in isolation. I don't need an implementation or even formal description of the type to write code.
Have to rely on unit tests to find any type errors.
Language is more terse. Less typing.
Types can be modified at runtime.
Edit and continue is much easier to implement.
Static Languages:
Compiler tells of all type errors.
Editors can offer prompts like Intellisense much more richly.
More strict syntax which can be frustrating.
More typing is (usually) required.
Compiler can do better optimization if it knows the types ahead of time.
To complicate things a little more, consider that languages such as C# are going partially dynamic (in feel anyway) with the var construct or languages like Haskell that are statically typed but feel dynamic because of type inference.
Dynamic programming languages basically do things at runtime that other languages do at Compile time. This includes extension of the program, by adding new code, by extending objects and definitions, or by modifying the type system, all during program execution rather than compilation.
http://en.wikipedia.org/wiki/Dynamic_programming_language
Here are some common examples
http://en.wikipedia.org/wiki/Category:Dynamic_programming_languages
And to answer your original question:
They're slow, You need to use a basic text editor to write them - no Intellisense or Code prompts, they tend to be a big pain in the ass to write and maintain. BUT the most famous one (javascript) runs on practically every browser in the world - that's a good thing I guess. Lets call it 'broad compatibility'. I think you could probably get a dynamic language interpretor for most operating systems, but you certainly couldn't get a compiler for non dynamic languages for most operating systems.

What is Haskell used for in the real world? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
There is a lot of hype around Haskell, however, it is hard to get information on how it is used in the real world applications. What are the most popular projects / usages of Haskell and why it excels at solving these problems?
What are some common uses for this
language?
Rapid application development.
If you want to know "why Haskell?", then you need to consider advantages of functional programming languages (taken from https://c2.com/cgi/wiki?AdvantagesOfFunctionalProgramming):
Functional programs tend to be much more terse than their ImperativeLanguage counterparts. Often this leads to enhanced
programmer productivity
FP encourages quick prototyping. As such, I think it is the best software design paradigm for ExtremeProgrammers... but what do I know?
FP is modular in the dimension of functionality, where ObjectOrientedProgramming is modular in the dimension of different
components.
The ability to have your cake and eat it. Imagine you have a complex OO system processing messages - every component might make state
changes depending on the message and then forward the message to some
objects it has links to. Wouldn't it be just too cool to be able to
easily roll back every change if some object deep in the call
hierarchy decided the message is flawed? How about having a history of
different states?
Many housekeeping tasks made for you: deconstructing data structures (PatternMatching), storing variable bindings (LexicalScope with
closures), strong typing (TypeInference), GarbageCollection, storage
allocation, whether to use boxed (pointer-to-value) or unboxed (value
directly) representation...
Safe multithreading! Immutable data structures are not subject to data race conditions, and consequently don't have to be protected by
locks. If you are always allocating new objects, rather than
destructively manipulating existing ones, the locking can be hidden in
the allocation and GarbageCollection system.
Apart from this Haskell has its own advantages such as:
Clear, intuitive syntax inspired by mathematical notation.
List comprehensions to create a list based on existing lists.
Lambda expressions: create functions without giving them explicit names. So it's easier to handle big formulas.
Haskell is completely referentially transparent. Any code that uses I/O must be marked as such. This way, it encourages you to separate code with side effects (e.g. putting text on the screen) from code without (calculations).
Lazy evaluation is a really nice feature:
Even if something would usually cause an error, it will still work as long as you don't use the result. For example, you could put 1 / 0 as the first item of a list and it will still work if you only used the second item.
It is easier to write search programs such as this sudoku solver because it doesn't load every combination at once—it just generates them as it goes along. You can do this in other languages, but only Haskell does this by default.
You can check out following links:
https://c2.com/cgi/wiki?AdvantagesOfFunctionalProgramming
https://learn.microsoft.com/archive/blogs/wesdyer/why-functional-programming-is-important-in-a-mixed-environment
https://web.archive.org/web/20160626145828/http://blog.kickino.org/archives/2007/05/22/T22_34_16/
https://useless-factor.blogspot.com/2007/05/advantage-of-functional-programming.html
I think people in this post are missing the most important point for anyone who has never used a functional programming language: expanding your mind. If you are new to functional programming then Haskell will make you think in ways you've never thought before. As a result your programming in other areas and other languages will improve. How much? Hard to quantify.
There is one good answer for what a general purpose language like Haskell is good for: writing programs in general.
For what it is used for in practice, I've three approaches to establishing that:
A tag cloud of Haskell library and app areas, weighted by frequency on Hackage.
Indicates that it is good for graphics, networking, systems programming, data structures, databases, development, text processing ...
Areas it is used in industry - a lot of DSLs, web apps, compiler design, networking, analysis, systems programming , ...
And finally, my opinion on what it is really strong at:
Problems where correctness matters, domain specific languages, and parallel and concurrent programming
I hope that gives you a sense on how broad your question is, if it is to be answered with any specificity.
One example of Haskell in action is xmonad, a "featureful window manager in less than 1200 lines of code".
From the Haskell Wiki:
Haskell has a diverse range of use
commercially, from aerospace and
defense, to finance, to web startups,
hardware design firms and lawnmower
manufacturers. This page collects
resources on the industrial use of
Haskell.
According to Wikipedia, the Haskell language was created out of the need to consolidate existing functional languages into a common one which could be used for future research in functional-language design.
It is apparent based on the information available that it has outgrown it's original purpose and is used for much more than research. It is now considered a general purpose functional programming language.
If you're still asking yourself, "Why should I use it?", then read the Why use it? section of the Haskell Wiki Introduction.
Haskell is a general purpose programming language. It can be used for anything you use any other language to do. You aren't limited by anything but your own imagination. As for what it's suited for? Well, pretty much everything. There are few tasks in which a functional language does not excel.
And yes, I'm the Rayne from Dreamincode. :)
I would also like to mention that, in case you haven't read the Wikipedia page, functional programming is a paradigm like Object Oriented programming is a paradigm. Just in case you didn't know. Haskell is also functional in the sense that it works; it works quite well at that.
Just because a language isn't an Object Oriented language doesn't mean the language is limited by anything. Haskell is a general-purpose programming language, and is just as general purpose as Java.
I have a cool one, facebook created a automated tool for rewriting PHP code. They parse the source into an abstract syntax tree, do some transformations:
if ($f == false) -> if (false == $f)
I don't know why, but that seems to be their particular style and then they pretty print it.
https://github.com/facebook/lex-pass
We use haskell for making small domain specific languages. Huge amounts of data processing. Web development. Web spiders. Testing applications. Writing system administration scripts. Backend scripts, which communicate with other parties. Monitoring scripts (we have a DSL which works nicely together with munin, makes it much easier to write correct monitor code for your applications.)
All kind of stuff actually. It is just a everyday general purpose language with some very powerful and useful features, if you are somewhat mathematically inclined.
From Haskell:
Haskell is a standardized, general-purpose purely functional
programming language, with
non-strict semantics and strong static
typing. It is named after logician
Haskell Curry.
Basically Haskell can be used to create pretty much anything you would normally create using other general-purpose languages (e.g. C#, Java, C, C++, etc.).
For example, for developing interactive, realtime HTML5 web applications. See Elm, the compiler of which is implemented in Haskell and the syntax of which borrows a lot from Haskell's.
This is a pretty good source for info about Haskell and its uses:
Open Source Haskell Releases and Growth

From OO to functional programming at 10,000 feet

I have been using f# and Haskell to learn functional programming for a while now. Until I can get f# approved at our company I must still use c#. I am still trying however to stay in the functional style as I have noticed several benefits.
Here is a typical problem.
There is a key-set table in the
database with 3 keys (6.5 million
rows)
There are 4 other supporting
tables of small to medium size.
There are complex formulas based on several inputs.
I have to use data from all of the above to calculate a value and associate it with each key-set row and send it back to the database. There is a lot of lookups to the other 4 tables. For performance sake it is all done in memory.
I know exactly how I would do the in OO with static dictionaries, object models, strategy patterns and so forth but in a functional way I cannot get rid of the bad smell of using some of these constructs.
I am currently making the following assumptions for a functional solution.
Static dictionaries are bad. It seems the function could have side affects.
I need an Calculate function the takes an immutable object(s) and returns an immutable object with the three keys and the calculated value. Inside this function there could be another function in the same style.
Traditional OO patterns are probably not going to work.
How would you design this at a high level?
Am I wrong? Have I missed anything?
No, you are not not wrong. Both OOP and functional programming have their benefits and their drawbacks.
A developer needs tho know how and when to use each development style. It's fortunate that C# supports in a way both development styles.
In my opinion, and I use both functional and oop programming styles on a daily bases, oop is best when dealing with complex interactions and inter dependencies between various abstract artifacts (entities, nouns etc. ). Functional programming is best used when dealing with algorithms, data transformations etc. e.g. situations where the complexity of statements needed to solve a given problem is great.
I generally use object oriented programming on my domain (entities, aggregates, value objects, repositories and events) and reserve functional programming for my service objects.
Most of the the time it comes to a smell, or feeling which is best, since in software development aren't clear cut cases either way, and experience and practice often is the best judge for a given choice.
If your looking for speed you may want to consider the underlying data structures your using. Dictionary<> in C# is a hash table while SortedDictionary<> in C# is a binary search tree.
F# and Haskell both do a good job of representing tree data structures. You may want to consider using a more specific data structure over the default ones C# provides.
At a high level I would figure out what performance characteristics your formulas display and compare them to different data structures (wikipedia is a good source if you need a refresher). Once you figure out what data structures to use then I'd worry about what implementations to use.
How would you design this at a high level?
Basically, you use higher-order functions to factor the work into reusable components with low syntactic overhead. Then you might like to migrate from imperative data structures to purely functional data structures (purely functional computation wrapped in side effects for IO like database writes). Finally, you might even track side effects (completely purely functional).
As a rough guide, these three gradations to complete purity are seen firstly in Lisp (largely impure), Standard ML (much heavier use of purely functional data structures) and Haskell (complete purity).
I cannot give more specifics without knowing the exact problem but you can rest assured many people are doing this on a daily basis now and it works extremely well.
Functional programming in an OO language tends to be wrong. It produces overly verbose code that doesn't perform well and is more error prone (such as writing deeply recursive functions in a language that doesn't support tail calls.)
Blockquote 1. Static dictionaries are bad. It seems the function could have side affects.
Either it does or does not have side effects. A static dictionary can be a good way to implement memoization in an OO language.
Blockquote 3. Traditional OO patterns are probably not going to work.
OO patterns work well in an OO language trying to shoe horn FP techniques into a OO language will produce verbose and brittle code. It is rather a lot like trying to use a screw driver with hammer techniques sure it produces a result but there are better ways. Try to use your tools in the best way possible. Certain FP techniques can be useful but completely ignoring the language isn't going to make for good quality code.

Why create a new programming language? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
What is the real benefit of creating a new programming language? It is highly unlikely that you are going to actually use it.
In short, how will the process of creating a new language make you a better programmer?
You will understand the decisions behind language design and garner a better overall understanding of the compromises made between readability, performance, and reliability.
Your familiarity with concepts such as recursion, closures, garbage collection, reference management, typing, data structures and how these things actually work will increase. Most programmers will utilize resources and language features better.
Similar to the way we learn new ways to code solutions when we use other languages, when we write our own languages, we explore new ways to create solutions. See Metaprogramming. Contrary to the what the question suggests, Domain Specific Languages are used in many environments.
If you're writing a compiler, you'll learn more about how computers work than you ever did before. (Depending on your goal, perhaps more than you intended to learn)
When I wrote my own sort routines in school, even re-implementations of good ones, it really drove home some of the weaknesses of some of the algorithms.
In short, there's an order of magnitude of difference in a programmer who knows how to use tools, and a programmer who knows how to make tools.
I can speak from experience here ...
Fun, Domain specific problem solving, Complexity in context
I love creating new languages for fun, and for tackling domain specific problems. A very simple example might be Wikipedia markup or something as complex as Erlang which specializes in concurrent processing.
Many general purpose languages are similar, because they are general purpose. Sometimes you need a more accurate abstraction of the mechanics of the problem you are solving. Another example would be the M4 macro language.
Remember a language is not magic, it is just a collection of defined grammatical structures with implied semantics. SQL is a good example of a language for a purpose, with that purpose defined in it's syntax and semantics.
Learning how languages work, what makes a language parsable, what makes semantics sensible and the implementation of this, I think can make you a better programmer.
compilers embody alot of theory that underpins computer science:
Translation, abstraction, interpretation, data structures, state .... the list goes on. Learning these things will make you understand the implications of your program and what goes on under the hood. You can of course learn things independently but compilers are a great context to learn complex topics such as DFA/NDFA automata, stack-based parsers, abstract syntax trees ....
compilers are beautiful machines I think :)
Multiple reasons:
bragging rights
economic incentives
extreme boredom
dissatisfaction with the hundreds of existing languages
untreated insanity
desire to implement language that facilitates new design concepts (like languages that make design patterns more straightforward to incorporate)
other reasons, perhaps
I think Jeff Attwood answers this well in this Coding Horror post -- though he's talking about a more general issue (why create any new library, framework, etc, when other artifacts in the same design space already exist), I suspect that exactly said broader viewpoint gives him a different and interesting perspective.
I will add that if you write a semantics, so that your language is an actual language and not merely what happens to be accepted by some particular implementation, you will learn an enormous amount about how to describe computational behaviors precisely:
You will learn what kinds of behaviors are and are not easy to describe—and prove correct.
You will learn how to trade off different kinds of formalisms for describing different kinds of features.
You will ultimately be a better programmer because the formalism and proof techniques you will learn will apply to all kinds of problems: locking techniques, safety properties in kernels, lock-free data structures, network protocols, and information security, to name just a few. All these areas are amenable to the same kind of formal treatment that is given to a programming language.
To pick just one example, if you give your language a static type system and you then prove that a well-type program is guaranteed to be memory-safe, you will learn just as much (on a different dimension) as you will by writing an interpreter or compiler.
EDIT: If you want to learn this stuff I think the easiest starting point is Benjamin Pierce's series of two books on Types and Programming Languages. There is also a graduate textbook by Glynn Winskel which is a little harder but more oriented toward semantics and proof techniques.
Creating Domain Specific Languages is very valuable. Instead of thinking only about general purpose languages, consider creating so-called "little languages" that clearly express abstractions in your project.
For example, in a recent project I decided to use a Command Pattern to drive a Service Layer. I found some repetition in my command code, so I wrote a little compiler that accepts a simple language that expresses commands and emits command implementations in the "underlying" language.
For the same reason that taking a Compiler Construction course at university will benefit you even if you never write a single compiler in your whole life. It's a look under the hood, if you may.
In addition to what altCognito said, which is a theoretical/academic perspective, some highly specialized languages are created to solve specific problems efficiently when existing "general-purpose" languages are either extremely inefficient for your task or there just isn't an easy-to-use existing alternative.
Granted, that such cases tend to be rare and if your first instinct on encountering a problem is "I need a new language for this.", then it is most likely you're missing something. There needs to be a fairly substantial gap in "available" tech and and your needs to warrant such an undertaking.
I think there are really two conceptually different answers to this. First, you gain an understanding of how compilers transform your code into executable code. This can help you make better decisions about how to structure your code to optimize (or allow it to be optimized) better. If, for instance, you knew that a certain construct would prohibit the compiler from inlining a code block or unrolling a loop, then you could avoid that if performance became a real concern.
Second, all current languages were invented (or derived) at some point in history. For each one of these, the likelihood that it would actually be used was potentially small, yet here they are. They all found their reason for being in the fact that someone wanted to do something that wasn't possible or easy to do in an existing language and decided to do something about it. Laziness (or the desire to let the computer do the work for you) is the mother of invention.
Just for fun... and then you'll realize that you cannot make anything better than all the languages that you thought they sucked xD (so you stop complaining about them).
how will the process of creating a new language make you a better programmer?
You're right, you may or may not use the language, but at the least the experience you will gain from doing it will benefit you to understand the implementation of programming languages and of certain things that you will be able to apply to future computation problems that you run into.
Writing a compiler or interpreter requires a very firm understanding in computer science theory. And if you're compiling to machine code instead of to another language, it requires a firm understanding in hardware design as well.
In addition to that, knowing how to design a compiler means you will have a better understanding of languages in general, and the languages you work with specifically. You will have a better appreciation for syntax and trade-offs the language designers took when they wrote their specification.
It's not that writing compilers makes you a better programmer. It's the deep understanding of language theory and compiler design that makes you better.
Mostly you do this for fun or to broaden your comprehension of a subject.
I disagree that creating new language influences performance - performance of what? IMHO execution speed should not depend on the language constructs but what the language is translated to - which is something different: like creating a syntax for a language and writting a compiler/virtual machine for it.
Because a talking frog is pretty neat.
I want a managed language that permits tinkering with its internals as standard practice. Kind of like Ruby's duck punching on a wider scale.
I should, as the client of a library, be able to swap out library functions that don't do what I want.
That's what drives me crazy with .NET. There are bugs in the framework Microsoft will not fix and thanks to GAC signing I cannot. And even if it were not for GAC signing, hotpatching a global library is a bad idea (might break some other application).
I for one don't care about how compilers work, don't care about learning new languages, and don't care about using scripting languages like perl and javascript. I'm much more interested in the ways big programs are constructed (or should be constructed). There are still no good solutions for making LARGE software as easy to use as prototyped code. Programming languages are not helping with that. They solve trivial problems like sorting and memory deallocation, and leave you struggling alone with problems that really matter (that keep you or your firm from losing money).

Resources