Functional Languages 101: What’s All the Fuss About?
Recorded at:
Getting lost again
by
Petr Sobotka
Petr
Re: Getting lost again
by
Scott Gregory
I'm not really understanding your question(s). By "where is the reason" do you mean why functions instead of objects or some other abstraction?
If you, like me, have a deep background in imperative languages, then functional languages can be a tough learning curve.
As much as possible, forget what you know about languages and how to structure programs. Get yourself a good introductory book, and re-learn programming over again (yes, hard!).
Remember that there is nothing magical about imperative languages or for() loops instead of recursion, just that we have programmed that way long enough that it has become "natural".
Good Luck
Re: Getting lost again
by
Rashid Jilani
All the experts feeding us the idea how beautiful FP is, never mentioned a single word about code reusability and readability. OO paradigm has been a success not because it was technically superior than Functional paradigm and vice versa, but because you can see the whole software as a blue print just looking at the API, and it is so easy to maintain and read someone else code.
I don’t claim to be an expert of programming paradigms especially FP, but say it for surety that no FP expert can convince you that reading and maintain the FP code is the easiest thing to do.
BTW besides my opinion about FP, I think the presenter (Rebecca Parsons) has done an awesome job to explain what a FP is all about for beginners.
Does functional language have the chance to become popular among mortals?
by
Chou Harry
Re: Does functional language have the chance to become popular among mortal
by
Chou Harry
Re: Getting lost again
by
Dmitry Tsygankov
Being able to pass functions around just like any other value. Being able to do something easily is a good thing, isn't it?
Immutability. There are a quite a few guidelines for programmers, which boil down some kind of limited immutability, the book Effective Java is a good place to start. Something that is completely immutable can be passed between threads without fear. Global variables and singletons are generally considered to be a bad practice. Reusing the same variable for two different purposes is not good for readability. Readonly variables are a good thing for readability, etc. In fact, I had started programming PL/SQL in a functional-style-without-functions a long time before I knew what functional programming was, and the programs I wrote weren't even mindblowingly multithreaded, so immutability is a good practice by itself.
Type systems. A good thing about the type systems of modern functional languages is that almost every single type signature can be omitted (powerful type inference). Which means you get both the conciseness of dynamic languages and guarantees of a static type system. Type systems of some languages allow you to even write type-level programs that check the correctness of your code at compile-time.
Lazy evaluation. When everything is immutable, you can change the order of execution with ease. That enables compilers to do powerful compile-time optimisations, calculate values exacty at the moment when they are needed. New abstractions like infinite lists become possible. There are analogous features of PL/SQL, which allow Oracle to do some query optimisations (I'm talking about the keywords deterministic, wnds, wnps, rnds, rnps here). Lazy evaluation also eliminates the difference between variables and functions without arguments, which means fewer abstractions, which is also a good thing.
Not all FP languages employ all of these features at the same level, only a few do. Common Lisp, for instance, goes away with just the first one. That's why I personally don't consider it a functional language.
Re: Getting lost again
by
Paul Topping
In FP languages, functions are just like those in other programming languages except they are not allowed to have side-effects: they can't set global variables or modify data via their arguments. They can only look at their arguments and return a result based on them.
Once you force functions to have no side-effects, you can do all kinds of nice things with them. They are just like mathematical functions and you can do mathematics with them. You can re-arrange functions in expressions in certain ways without changing the meaning of the expression.
When functions do not have side-effects, the implementation of the language can do some neat tricks:
1) It can cache function results with their arguments. If a new function call has the same arguments as an earlier cached one, it does not need to execute the function but just return the cached result.
2) It can execute terms in an expression in any order and always get the same result.
Code in Clojure
by
Alexandru Repede
Example 1 - Length of a list:
(defn my-length [lst]
(loop [len 0 x lst]
(if (empty? x)
len
(recur (+ 1 len) (rest x)))))
user=> (my-length '(1))
1
user=> (my-length '(1 2 3 4))
4
user=> (my-length '())
0
Example 2 - Square each element of a list:
(defn squares [lst]
(loop [sqrs '() x lst]
(if (empty? x)
(reverse sqrs)
(recur (cons (* (first x) (first x)) sqrs) (rest x)))))
user=> (squares '(1 2 3 4))
(1 4 9 16)
More complicated example - Map:
(defn my-map [func lst]
(loop [res '() x lst]
(if (empty? x)
(reverse res)
(recur (cons (func (first x)) res) (rest x)))))
user=> (my-map (fn [x] (* x 2)) '(1 2 3))
(2 4 6)
PS: thanks to the Clojure community for translating. more info here:
stackoverflow.com/questions/3941239/can-you-tra...
Re: Getting lost again
by
Anton Ivanov
But I guess that you can think of many of functional languages as a different approach to problem solving. For example, most of the people that write say in Java (as I do) think that assignment operator should be a fundamental part of any language. But this is not so, for example in Scheme it is possible to write rather complicated programs without ever using any assignment operators. In other words the notion of time is not required in order to perform some computations (the notion of time means that we have to know when a variable x becomes equal to some value x0 in order to perform the computation correctly). From this it may follow that maybe the problems with concurrent programming that we experience in other languages like Java (it is relatively hard to write correct concurrent programs even having such a wonderful library as java.util.concurrent) are not a fundamental part of the computation itself.
Maybe it is just that imperative languages are a wrong tool for concurrent programming? This is just an example of some of the interesting things one may observe looking at some functional languages.
By the way, some time ago I discovered for myself this wonderful course from MIT 'Structure and Interpretation of Computer Programs', the videos and the book are available online, maybe watching it can give a more detailed introduction to Scheme and functional programming
ocw.mit.edu/courses/electrical-engineering-and-...
mitpress.mit.edu/sicp/full-text/book/book.html
It is like learning to write code all over again=)
Recently I also heard Robert Martin talking about functional programming and this course here pragprog.com/podcasts/show/32 and he gave a rather good explanation and maybe answered your question (although, not all the talk is about functional languages)
Personally I am now convinced to look more closely at Closure=) It is actually a shame that I did not notice this language earlier
Re: Does functional language have the chance to become popular among mortal
by
Gresham Paul
Re: Does functional language have the chance to become popular among mortal
by
Gresham Paul
Code in Scala
by
Steve Thompson
// A is a generic parameter, match/case is akin to a switch/case
// mechanism in Java, Nil denotes an empty list, and the =>
// operator in this context separate the case from its associated
// logic. Return is not used as Scala methods return the last
// expression evaluated.
def length[A](list: List[A]): Int = list match {
case Nil => 0
case first :: theRest => 1 + length(theRest)
}
This syntax still takes some getting used to for someone more used to Java for example, but it is a lot less noisy than the Scheme code shown.
As far as doing things like multiplying elements of an integer list, this becomes visually pretty easy to read with Scala:
// Notice the lambda (anonymous function) given to map
def timesTwo(values: List[Int]): List[Int] =
values.map((value: Int) => value * 2)
// or, more simply because of type inference
def timesTwo(values: List[Int]): List[Int] =
values.map(value => value * 2)
// or, even simpler still (because creating an identifier for
// each value just adds more ceremony to our code), here is
// the same with 'placeholder' syntax
def timesTwo(values: List[Int]): List[Int] = values.map(_ * 2)
I think that cognitively, this kind of declarative code is easier to grasp for people who haven't been raised in an imperative programming world, because what's expressed reads a lot like how we think: 'given a list of integers, create a new list where each value from the original has been doubled'. We state WHAT we are trying to do, without going into all the gory details of HOW it might be done.
But these two examples, because they are so trivial, hardly make the case for functional. A more real life example of functional comes in to play when the following simple Java code is considered:
// Typical open resource/do something with resource/close resource
public <T> void save(T item)
{
Connection connection = Db.openConnection();
try { connection.store(item); } finally { connection.close(); }
}
This is how (for the object database db4o) we might perform a save. The trouble is, we would largely have to duplicate the connection-try-finally for other operations like delete as well. This isn't very DRY. To rectify this, we can separate what stays the same (boilerplate) from what varies in the following way:
// We'll pass in a function as a parameter. The signature for this
// is Connection => Unit, which basically means the function takes
// a Connection but doesn't return anything.
def transact(f: Connection => Unit): Unit = {
val connection = Db.openConnection()
try{ f(connection) } finally { connection.close() }
}
// Now our save can be very DRY
def save[A](item: A) = transact(_.store(item))
// And similarly other operations
def delete[A](item: A) = transact(_.delete(item))
// This can be easily tied into collections. Note that this is
// potentially much more efficient than calling transact repeatedly
// for each item
def deleteAll[A](items: List[A]) = transact(items foreach _.delete)
Just as a parting observation I'd like to mention that increasingly it is getting hard to pick up a language without noticing functional characteristics. Python, Ruby, Groovy, C#, JavaScript, ActionScript, etc all support FP to varying degrees, and Java will eventually as well. Because of the growing ubiquity of these concepts, it is becoming much harder to try and ignore them.
Availability of Parser Combinator Example?
by
Morgan Creighton
I could not find them in the slides here qconlondon.com/dl/qcon-london-2010/slides/Rebec... and unfortunately the video did not reveal them.
Use of continuations for parallel workflows
by
Nermin Serifovic
Re: Getting lost again
by
Jack Repenning
No proper program contains an indication which as an operator-applied occurrence identifies an operator-defining occurrence which as an indication-applied occurrence identifies an indication-defining occurrence different from the one identified by the given indication as an indication-applied occurrence.





Hello stranger!
You need to Register an InfoQ account or Login to post comments. But there's so much more behind being registered.Get the most out of the InfoQ experience.
Tell us what you think