Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
VikingofRock
Aug 24, 2008




This is a thread for discussing and asking questions about functional programming and functional languages.

What is functional programming?

To quote the Haskell wiki:

quote:

In functional programming, programs are executed by evaluating expressions, in contrast with imperative programming where programs are composed of statements which change global state when executed. Functional programming typically avoids using mutable state.

Additionally, functions are often treated as just-another-value, meaning that functions-of-functions (and functions-of-functions-of-functions, etc) are quite common. This allows you to write very, very general code, to a degree which is uncommon in imperative languages.

What are some functional languages?
Some of the more popular functional languages are:

Additionally, Elm (http://elm-lang.org/) is an up-and-coming functional language which seems very cool and is probably worth a look.

General Functional Programming Resources

Language-Specific Information and Resources
There are excellent threads in this forum for LISP and its dialects, Erlang, and Scala. I won't bother to repeat the information in those threads here.


Haskell is a functional language with a focus on purity--that is, lack of side effects in its functions. This makes Haskell code very easy to reason about and to test, because calling a function with the same arguments will always yield the same result. Haskell is very strongly typed, and you can often tell what a function does just by looking at its type signature. Haskell has a heavy influence from category theory, and as a result Haskell code can be very elegant, but also very confusing for beginners. Fear not though, soon you will understand applicative functors, monoids and monads and will be happily writing beautiful, concise code (at least in theory).

Haskell books:
  • Learn You A Haskell: This book is written in a somewhat snarky tone, which turns some people off, but it's a pretty good introduction to Haskell. In particular, I like the sections where the author lists a series of useful functions for manipulating whatever he has just introduced.
  • Real World Haskell: This book is somewhat more serious and practical than LYAH, and covers a few more useful libraries. It is also an excellent read.
  • Haskell Programming From First Principles: An up-to-date introduction to Haskell, still in early access. Recommended by Charlie Mopps

Other resources:


(contributed by Arcsech)
F# is a functional language descended from the SML/OCaml family and based on Microsoft's .NET platform. This allows easy interop with C# and other .NET applications & libraries, but can lead to some awkwardness as much of the .NET standard library wasn't designed with functional programming in mind. In addition to .NET interop, you get some really awesome languages features such as 1) type providers, which use data files, database connections, or even other programming languages to inform your type system and Visual Studio's autocomplete, 2) Units of Measure, which let you tag primitive types with additional type data to reflect their units and have the compiler do dimensional analysis at compile time, and 3) computation expressions which let you write code in a way similar to Haskell's do-notation, but with more flexibility (and in my opinion, a bit more readable).

F# resources:
  • Try F#: Try F# in your browser!
  • F# For Fun and Profit: A website with a thorough "Why F#?" series, well worth looking through to get a sense of what's available in F#.
  • F# Foundation: A pretty good directory of F# resources.

Some cool F# things:
  • Websharper: Write webapps in 100% F#. F# on the server, HTML combinators to generate HTML, and an F#->JS transpiler (although it can work with normal HTML templates if you so desire)
  • Visual F# Power Tools: While Visual Studio supports F# by default, it's kind of half-assed. This extension makes it a bit more fully-assed and generally improves quality of life quite a bit.


(contributed by fart simpson)

Elm is a pure, strictly evaluated functional language descended from Haskell, with bits and pieces taken from other ML-family languages like F#. It's unique in that it's not a general purpose programming language like the others mentioned in this thread, but rather it's a browser-based, Functional Reactive Programming UI language. There are other FRP implementations, but Elm is the only language I know of dedicated to the concept rather than being a library.

What is Functional Reactive Programming?

Functional Reactive Programming, or FRP, is a relatively new approach to building UI and animation (among other things). It abstracts events and callbacks into first-class, time-varying values that Elm calls Signals. In Elm, you define your program as pure functions that transform inputs to outputs, and then map input Signals over these functions. As a basic "Hello World" type example, the following function takes an (Int, Int) tuple and returns an Element (which just means "something that can be drawn to the screen"):
code:
render : (Int, Int) -> Element
render (x, y) = Graphics.Element.show (x, y)
We can then map the current position of the mouse onto this render function without our render function to produce a Signal Element, which means a time-varying object that is drawn to screen:
code:
-- Mouse.position is a built-in input Signal in Elm of type "Signal (Int, Int)"
main : Signal Element
main = Signal.map render Mouse.position
This program will always show the current mouse position, because as the mouse is moved, the input Signal "Mouse.position" is automatically updated, and the values flow through each function, updating their values in turn.

Every input to your program is handled in the same way, and complex behavior is defined as compositions of these basic building blocks. This paradigm naturally leads to a specific architectural pattern we call The Elm Architecture that ends up looking like this:
code:
-- MODEL (Where you define the data structures that will be used to represent your program's state)

type alias Model = { ... }


-- UPDATE (Where you define the possible actions, map input Signals to these actions, 
--         and write one or more state machines that define how your program state updates on each action)

type Action = Reset | ...

update : Action -> Model -> Model
update action model =
  case action of
    Reset -> ...
    ...


-- VIEW (Where you define how to visually display your program model. 
--       In Elm, you don't define visual transitions as such, rather 
--       you define what the entire output should look like given any possible model)

-- view can also be Model -> Element
view : Model -> Html 
view =
  ...
These sections can be composed together from smaller subsections that live in different modules, with each piece being pure and stateless. At the very end, you tie everything together by mapping input Signals onto the update function. It leads to a very clean style of code that is easy to reason about and test, and the guarantees of the language allow some cool things like the time traveling debugger and the near-total elimination of runtime exceptions.

There's a lot of other stuff to like about Elm. It has a helpful, growing community, an emphasis on making functional programming concepts approachable and easy to learn, a package manager that enforces semantic versioning, a virtual-dom rendering backend that's really fast, real-time modification of currently running code, a simple and powerful FFI, and more.

The best places to learn more are the official website and the mailing list.

:siren:Cool functional stuff written by goons::siren:

---

I don't know enough about the other functional languages to write an introduction for them, but if anyone posts some information, resources, example code, etc for other languages I will add it to this OP.

VikingofRock fucked around with this message at 05:03 on Jan 2, 2016

Adbot
ADBOT LOVES YOU

VikingofRock
Aug 24, 2008




fart simpson posted:

For anyone looking to learn functional programming I wouldn't hesitate to consider Elm. It's very similar to a strictly evaluated, simplified, streamlined Haskell. Unlike many of the other FP languages, it retains the complete purity of Haskell, but it doesn't get bogged down in category theory. And it's a compile-to-js UI language so it's easy to get started (you don't even need to download anything for a while if you don't want to) and you get instant visual feedback. It also has first class support for its own unique take on Functional Reactive Programming, which is a very interesting take on managing interactions and state, sort of like an abstraction on top of callbacks.

I can write a lot more about Elm if anyone's interested.

Please do, I'd love to add it to the OP.

VikingofRock
Aug 24, 2008




Bloody posted:

What's a monad?

I'll take a stab at this. Despite talking primarily about Haskell's monads I'm going to use a more C++-like syntax because I figure that's what non-functional programmers are used to.

Monads (like many things) are defined by how they act when you apply certain functions to them. In Haskell, these functions are called "return" and ">>=". I'll talk about them in a second, but first I want to say that monads are incomplete types by themselves. This is just like how C++'s std::vector needs a template parameter (like <int>) to become a complete type. For our purposes we will say the monad has type Monad and its parameter has type T (so the C++ version would be a Monad<T>).

"return" is a function which takes something of some type T, and gives you a Monad<T>. The C++ vector equivalent would be a template function which takes a T and gives you a vector<T>.

">>=" is a function which is used to chain together operations. It takes a Monad<T> and a function from T to Monad<U>, and returns a Monad<U>.

There are a few rules on how these functions work together:
  • If you pass ">>=" the result of "return(x)" and a function "f", you must get back the same thing as you would passing "x" directly to "f".
  • If you pass ">>=" a Monad<T> and the function "return", you must get back the original Monad<T>.
  • ">>=" must be associative.

And that's it! Anything that fits that description is a monad. They sound pretty weird at first but if you play around with them a bit they'll become pretty clear, and you'll find yourself defining them in other languages because they are useful as hell.

VikingofRock
Aug 24, 2008




Updated the OP with cool stuff from this page. Thanks HappyHippo, giogadi, and Arcsech!

VikingofRock
Aug 24, 2008





Thanks, this is great. I added it to the OP. Also, drat, I really need to get into Elm more!

VikingofRock
Aug 24, 2008




Real World Haskell has some exercises as well.

VikingofRock
Aug 24, 2008




So apparently facebook is re-writing their content classification code in Haskell. Pretty interesting to see the language in use by one of the bigger tech companies around!

VikingofRock
Aug 24, 2008




Speaking of interesting math-y books, can anyone recommend a good book on category theory? I've been meaning to read up on it more.

VikingofRock
Aug 24, 2008




I'm not really interested in reading it for functional programming purposes--I just thought this thread would be a good place to ask since there is an overlap between the two subjects.

VikingofRock
Aug 24, 2008




I've been thinking about implementing Conway's Game of Life in Haskell. Does anyone have any recommendations for graphics libraries to use?

VikingofRock
Aug 24, 2008




Testiclops posted:

Gloss is pretty nice

I'm looking over it now and it seems pretty promising. Thanks!

VikingofRock
Aug 24, 2008




Haskell question: I want to upgrade ghc to 7.10, because a lot of the new stuff looks pretty sweet. What's the best way to do this without breaking everything I've installed with cabal? If that's not possible, what's the best way to fix everything I break?

My Haskell installation is the one provided through https://www.haskell.org/platform/, and it's version 2013.2.0.0 if that matters.

VikingofRock
Aug 24, 2008




gonadic io posted:

(.).(.) is real, and occasionally useful.

I had never seen that operator before, but after sitting down with a pen and paper and figuring out what it does, that's really useful! I'll have to remember that.

VikingofRock
Aug 24, 2008




gonadic io posted:

I'm trying to cut back a little on how pointfree my code is.

Is this mostly out of readability concerns?

Another question I've been pondering: does pointfree style affect performance through memoization? This article seems to indicate that it does, but I'm not sure I fully understand what it's saying.

VikingofRock
Aug 24, 2008




fart simpson posted:

You're the problem.

Guilty as charged.

VikingofRock
Aug 24, 2008




drat, those are some nice error messages.

VikingofRock
Aug 24, 2008




Is there an up-to-date tutorial on regexes in Haskell? It seems like every tutorial is out-of-date, and the documentation on Hackage is fairly lacking.

VikingofRock
Aug 24, 2008




Barnyard Protein posted:

:eyepop: Your Elm posts always make me want to do more with Elm. I've done a little, but not enough.

Same here. I've never really had any desire to do web stuff, but fart simpson's elm posts make it look so slick.

VikingofRock
Aug 24, 2008




Munkeymon posted:

Yep, that's it. I thought I was being all clever there by avoiding implicitly creating a bunch of basically-useless single-element lists.

I think that would get compiled away anyways, but if not I think this would work:

code:
flatten : Tree a -> List a
flatten tree = 
    case tree of
      Empty -> []
      Node value left right -> 
          flatten left ++ (value :: flatten right)
edit: You might not even need the parens, depending on operator precedence.

VikingofRock fucked around with this message at 23:52 on Dec 30, 2015

VikingofRock
Aug 24, 2008




Munkeymon posted:

Am I just super bad at this or am I finding the compiler bugs? Both?

code:
fold : (a -> b -> b) -> b -> Tree a -> b
fold func acc tree = 
    case tree of
      Empty -> acc
      Node value left right -> 
          --(func value (fold func acc left)) `func` (fold acc func right) -- crashes the compiler
        let 
          partial : Tree a -> b
          partial = (fold func acc)
        in
          (func value (partial left)) `func` (partial right)
code:
The left argument of `func` is causing a type mismatch.

101|           (func value (partial left)) `func` (partial right)
`func` is expecting the left argument to be a:

    a

But the left argument is:

    a

Hint: A type annotation is clashing with itself or with a sub-annotation. This
can be particularly tricky, so read more about it.
<[url]https://github.com/elm-lang/elm-compiler/blob/0.16.0/hints/type-annotations.md[/url]>
Uh, ok? :confused:

Not sure what's up with that error message, but I think your problem is that in the last line, func value (partial left) is a b, and (partial right) is also a b, so you can't apply `func` to them.

VikingofRock
Aug 24, 2008




Charlie Mopps posted:

For people wanting to learn Haskell i can recommend the book Haskell Programming From First Principles. Its quite expensive ($60) and still in early access, but its up to ~1000 pages already. Its pretty much the only book thats up to date and explains Haskell from the basis. Its goal is to explain Haskell in such a way that you can learn and understand any Haskell library thats out there, instead of teaching you say web dev with a framework or whatever. A sample can be found here.

Added this to the OP. Thanks for the recommendation!

VikingofRock
Aug 24, 2008




Hughmoris posted:

I dabble with programming as a hobby, mainly in Perl and Python. Trying my hand at functional programming with Haskell. I've read in multiple places that functional programming makes concurrency/parallel programming much easier, and that functional programming scales really well.

Could someone explain at a simpleton level why these things are easier with functional programming compared to OO/imperative languages?

Most fundamentally, lack of mutable state means that you don't have to worry about data races (except in things like file access), and it allows for *very* lightweight threads. Also, the more expressive syntax lets you experiment with parallelization more simply (e.g. replacing calls to `map` with calls to `parmap`).

VikingofRock
Aug 24, 2008




Lists in Haskell are singly-linked lists, which can be pretty inefficient if you have to traverse them more than once. If you have a lot of lists (or Strings, which are really just lists of chars), you might want to try replacing them with a more efficient data structure (e.g. Vectors or ByteStrings).

Other than that, it's hard to diagnose efficiency problems without seeing any code.

VikingofRock
Aug 24, 2008




xtal posted:

That's good to know, I was under the wrong impression because the first step in every tutorial is Template Haskell.

Which tutorials were you using? I've been meaning to try out lenses.

VikingofRock
Aug 24, 2008




New version of Elm is out.

VikingofRock
Aug 24, 2008




Shinku ABOOKEN posted:

but... but... but... I liked my primes :cry:

Me too! I also liked the [1..5] syntax and back ticks. I suppose I can see the argument for removing all three though.

VikingofRock
Aug 24, 2008




xtal posted:

What is the best language to use on a Raspberry Pi? Haskell runs fine but lens has been compiling for over a day

How is ghc cross-compilation? Could you compile it on a different machine and then just move the binaries over?

Adbot
ADBOT LOVES YOU

VikingofRock
Aug 24, 2008




Smoke_Max posted:

I just read about the FTP controversy in Haskell and it seemed to me to have been a solid move, but one detail is still nagging me. What's the rationale behind (,)'s Foldable instance? I understand how it works, but why is it even defined? Is it a case of "because we can"? I honestly cannot see much use for it besides creating confusion (length (1, 2) = 1 says hi). Personally, by making well typed code do the wrong thing, all it does for me is make me less confident in the type checker.

(As an aside, why did it stop at (,)? What about (,,), (,,,), etc.?)

As far as I know, (,) is Foldable pretty much exactly "because we can". It, and the Foldable instance for Either, are pretty controversial in the Haskell community for exactly the reasons you posted.

  • Locked thread