I've been looking at Haskell lately and it seems like a very nice way to watch programming problems from an alternative point of view - alternative to my usual imperative (I have a strong C++ background) view, at least.
However, all the articles I see seem to deal with the same kinds of programming problems:
Parsers
Compilers
Numeric computation problems
I'd like to give Haskell a try myself, by writing some GUI application. Hence, I'm wondering: does it make sense to write event-driven systems like GUIs in a functional programming language like Haskell? Or is that a problem domain at which imperative languages excel? Unfortunately it still takes quite some time for me to switch my mind to 'functional' mode, so I have a hard time deciding argueing against or in favor of using a functional programming language for an event-driven system.
I'd also be interested in examples of GUI applications (or event-driven systems, in general) which are implemented in Haskell.
Here's a couple of Google keywords for you:
Functional Reactive Programming (FRP), a programming paradigm for, well reactive (aka event-driven) programming in purely functional languages,
Leksah, a Haskell IDE written in Haskell,
Yi, an Emacs-like editor which replaces Lisp with Haskell as the implementation, configuration, customization and scripting language,
Super Monao Bros. (yes, you guessed it, a Jump&Run game)
Frag (First-Person Shooter)
Purely Functional Retrogames is a 4-part series of blog articles about how to write games in a purely functional language, explained using Pacman as the example. (Part 2, Part 3, Part 4.)
xmonad is an X11 window manager written in Haskell.
Also, looking at how the various Haskell GUI Libraries are implemented may give some ideas of how interactive programs are made in Haskell.
Here's an example using epoll to implement an event driven web server: http://haskell.org/haskellwiki/Simple_Servers
Take a look at this wikibooks article, it's a basic wxHaskell tutorial. In particular see the Events section.
I recommend spending some quality time with Haskell and FP in general before jumping in to develop a fully-fledged application so you can get more familiarized with Haskell, since it's quite different from C++
xmonad is event-driven -- see the main event handling loop, which takes messages from the X server, and dispatches to purely functional code, which in turn renders state out to the screen.
"Functional reactive programming" was already mentioned, but it may seem complicated if you're looking at it for the first time (and if you're looking at some advanced articles, it will look complicated no matter how long have you studied it :-)). However, there are some very nice articles that will help you understand it:
Composing Reactive Animations by Conal Elliott shows a "combinator library" (a common programming style in functional languages) for describing animations. It starts with very simple examples, but shows also more interesting "reactive" bit in the second part.
Yampa Arcade is a more evolved demo of Functional Reactive Programming. It uses some advanced Haskell features (such as Arrows), but is still very readable. Getting it to actually run may be more complicated, but it is an excellent reading.
Haskell School of Expression by Paul Hudak is a book which teaches Haskell using multimedia and graphics (including some animations etc.). It is an excellent reading, but it takes more time as it is an entire book :-).
I find my way to functional programming through F#, which is a bit less "pure" compared to Haskell, but it gives you a full access to .NET libraries, so it is easy to use "real-world" technologies from a functional language. In case you were interested, there are a couple of examples on my blog.
Related
First off, I'm aware that there are many questions related to this, but none of them seemed to help my specific situation. In particular, lua and python don't fit my needs as well as I could hope. It may be that no language with my requirements exists, but before coming to that conclusion it'd be nice to hear a few more opinions. :)
As you may have guessed, I need such a language for a game engine I'm trying to create. The purpose of this game engine is to provide a user with the basic tools for building a game, while still giving her the freedom of creating many different types of games.
For this reason, the scripting language should be able to handle game concepts intuitively. Among other things, it should be easy to define a variety of types, sub-type them with slightly different properties, query and modify objects dynamically, and so on.
Furthermore, it should be possible for the game developer to handle every situation they come across in the scripting language. While basic components like the renderer and networking would be implemented in C++, game-specific mechanisms such as rotating a few hundred objects around a planet will be handled in the scripting language. This means that the scripting language has to be insanely fast, 1/10 C speed is probably the minimum.
Then there's the problem of debugging. Information about the function, stack trace and variable states that the error occurred in should be accessible.
Last but not least, this is a project done by a single person. Even if I wanted to, I simply don't have the resources to spend weeks on just the glue code. Integrating the language with my project shouldn't be much harder than integrating lua.
Examining the two suggested languages, lua and python, lua is fast(luajit) and easy to integrate, but its standard debugging facilities seem to be lacking. What's even worse, lua by default has no type-system at all. Of course you can implement that on your own, but the syntax will always be weird and unintuitive.
Python, on the other hand, is very comfortable to use and has a basic class system. However, it's not that easy to integrate, it's paradigm doesn't really involve type-checking and it's definitely not fast enough for more complex games. I'd again like to point out that everything would be done in python. I'm well aware that python would likely be fast enough for 90% of the code.
There's also Scala, which I haven't seen suggested so far. Scala seems to actually fulfill most of the requirements, but embedding the Java VM with C doesn't seem very easy, and it generally seems like java expects you to build your application around java rather than the other way around. I'm also not sure if Scala's functional paradigm would be good for intuitive game-development.
EDIT: Please note that this question isn't about finding a solution at any cost. If there isn't any language better than lua, I will simply compromise and use that(I actually already have the thing linked into my program). I just want to make sure I'm not missing something that'd be more suitable before doing so, seeing as lua is far from the perfect solution for me.
You might consider mono. I only know of one success story for this approach, but it is a big one: C++ engine with mono scripting is the approach taken in Unity.
Try the Ring programming language
http://ring-lang.net
It's general-purpose multi-paradigm scripting language that can be embedded in C/C++ projects, extended using C/C++ code and/or used as standalone language. The supported programming paradigms are Imperative, Procedural, Object-Oriented, Functional, Meta programming, Declarative programming using nested structures, and Natural programming.
The language is simple, trying to be natural, encourage organization and comes with transparent implementation. It comes with compact syntax and a group of features that enable the programmer to create natural interfaces and declarative domain-specific languages in a fraction of time. It is very small, fast and comes with smart garbage collector that puts the memory under the programmer control. It supports many programming paradigms, comes with useful and practical libraries. The language is designed for productivity and developing high quality solutions that can scale.
The compiler + The Virtual Machine are 15,000 lines of C code
Embedding Ring Interpreter in C/C++ Programs
https://en.wikibooks.org/wiki/Ring/Lessons/Embedding_Ring_Interpreter_in_C/C%2B%2B_Programs
For embeddability, you might look into Tcl, or if you're into Scheme, check out SIOD or Guile. I would suggest Lua or Python in general, of course, but your question precludes them.
Since noone seems to know a combination better than lua/luajit, I think I will leave it at that. Thanks for everyone's input on this. I personally find lua to be very lacking as a high-level language for game-programming, but it's probably the best choice out there. So to whomever finds this question and has the same requirements(fast, easy to use, easy to embed), you'll either have to use lua/luajit or make your own. :)
I would like to ask you about what formal system could be more interesting to implement from scratch/reverse engineer.
I've looked through some existing and open-source projects of logical/declarative programming systems. I've decided to make up something similar in my free time, or at least to catch the general idea of implementation.
It would be great if some of these systems would provide most of the expressive power and conciseness of modern academic investigations in logic and its relation with computational models.
What would you recommend to study at least at the conceptual level? For example, Lambda-Prolog is interesting particularly because it allows for higher order relations, but AFAIK is based on intuitionist logic and therefore lack the excluded-middle principle; that's generally a disadvantage for me.
I would also welcome any suggestions about modern logical programming systems which are less popular but more expressive/powerful.
Prolog was the first language which changed my point of view at programming. But later I found it to be not so high-level as I'd like to see it.
Curry - I've tried only Munster CC, and found it somewhat inconvenient. Actually, at this point, I decided to stop ignoring Haskell.
Mercury has many things which I wanted to see in Prolog. I have a really good expectation about the possibility to distinguish modes of rules. Programs written in Mercury should inspire compiler to do a lot of optimizations (I guess).
Twelf.
It generalizes lambda-prolog significantly, and it's a logical framework and a metalogical framework as well as a logic programming language. If you need a language with a heavy focus on logic as well as computation, it's the best I know of.
If I were to try to extend a logic based system, I'd choose Prolog Cafe as it is small, open sourced, standards compliant, and can be easily integrated into java based systems.
For the final project in a programming languages course I took, we had to embed a Prolog evaluator in Scheme using continuations and macros. The end result was that you could freely mix Scheme and Prolog code, and even pass arbitrary predicates written in Scheme to the Prolog engine.
It was a very instructive exercise. The first 12 lines of code (and and or) literally took about 6 hours to write and get correct. It was pretty much the search logic, written very concisely using continuations. The rest followed a bit more easily. Then once I added the unification algorithm, it all just worked.
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 4 years ago.
Improve this question
I've recently caught the FP bug (trying to learn Haskell), and I've been really impressed with what I've seen so far (first-class functions, lazy evaluation, and all the other goodies). I'm no expert yet, but I've already begun to find it easier to reason "functionally" than imperatively for basic algorithms (and I'm having trouble going back where I have to).
The one area where current FP seems to fall flat, however, is GUI programming. The Haskell approach seems to be to just wrap imperative GUI toolkits (such as GTK+ or wxWidgets) and to use "do" blocks to simulate an imperative style. I haven't used F#, but my understanding is that it does something similar using OOP with .NET classes. Obviously, there's a good reason for this--current GUI programming is all about IO and side effects, so purely functional programming isn't possible with most current frameworks.
My question is, is it possible to have a functional approach to GUI programming? I'm having trouble imagining what this would look like in practice. Does anyone know of any frameworks, experimental or otherwise, that try this sort of thing (or even any frameworks that are designed from the ground up for a functional language)? Or is the solution to just use a hybrid approach, with OOP for the GUI parts and FP for the logic? (I'm just asking out of curiosity--I'd love to think that FP is "the future," but GUI programming seems like a pretty large hole to fill.)
The Haskell approach seems to be to just wrap imperative GUI toolkits (such as GTK+ or wxWidgets) and to use "do" blocks to simulate an imperative style
That's not really the "Haskell approach" -- that's just how you bind to imperative GUI toolkits most directly -- via an imperative interface. Haskell just happens to have fairly prominent bindings.
There are several moderately mature, or more experimental purely functional/declarative approaches to GUIs, mostly in Haskell, and primarily using functional reactive programming.
Some examples are:
reflex-platform, https://github.com/reflex-frp/reflex-platform
grapefruit, http://hackage.haskell.org/package/grapefruit-ui-gtk
reactive, http://hackage.haskell.org/package/reactive-glut
wxFruit, http://hackage.haskell.org/package/wxFruit
reactive-banana, http://hackage.haskell.org/package/reactive-banana
For those of you not familiar with Haskell, Flapjax, http://www.flapjax-lang.org/ is an implementation of functional reactive programming on top of JavaScript.
My question is, is it possible to have a functional approach to GUI programming?
The key words you are looking for are "functional reactive programming" (FRP).
Conal Elliott and some others have made a bit of a cottage industry out of trying to find the right abstraction for FRP. There are several implementations of FRP concepts in Haskell.
You might consider starting with Conal's most recent "Push-Pull Functional Reactive Programming" paper, but there are several other (older) implementations, some linked from the haskell.org site. Conal has a knack for covering the entire domain, and his paper can be read without reference to what came before.
To get a feel for how this approach can be used for GUI development, you might want to look at Fudgets, which while it is getting a bit long in the tooth these days, being designed in the mid 90s, does present a solid FRP approach to GUI design.
Windows Presentation Foundation is a proof that functional approach works very well for GUI programming. It has many functional aspects and "good" WPF code (search for MVVM pattern) emphasizes the functional approach over imperative. I could bravely claim that WPF is the most successful real-world functional GUI toolkit :-)
WPF describes the User interface in XAML (although you can rewrite it to functionally looking C# or F# too), so to create some user interface you would write:
<!-- Declarative user interface in WPF and XAML -->
<Canvas Background="Black">
<Ellipse x:Name="greenEllipse" Width="75" Height="75"
Canvas.Left="0" Canvas.Top="0" Fill="LightGreen" />
</Canvas>
Moreover, WPF also allows you to declaratively describe animations and reactions to events using another set of declarative tags (again, same thing can be written as C#/F# code):
<DoubleAnimation
Storyboard.TargetName="greenEllipse"
Storyboard.TargetProperty="(Canvas.Left)"
From="0.0" To="100.0" Duration="0:0:5" />
In fact, I think that WPF has many things in common with Haskell's FRP (though I believe that WPF designers didn't know about FRP and it is a bit unfortunate - WPF sometimes feels a bit weird and unclear if you're using the functional point of view).
I would actually say that functional programming (F#) is much better tool for user interface programming than for example C#. You just need to think about the problem a little bit differently.
I discuss this topic in my functional programming book in Chapter 16, but there is a free excerpt available, which shows (IMHO) the most interesting pattern that you can use in F#. Say you want to implement drawing of rectangles (user pushes the button, moves the mouse and releases the button). In F#, you can write something like this:
let rec drawingLoop(clr, from) = async {
// Wait for the first MouseMove occurrence
let! move = Async.AwaitObservable(form.MouseMove)
if (move.Button &&& MouseButtons.Left) = MouseButtons.Left then
// Refresh the window & continue looping
drawRectangle(clr, from, (move.X, move.Y))
return! drawingLoop(clr, from)
else
// Return the end position of rectangle
return (move.X, move.Y) }
let waitingLoop() = async {
while true do
// Wait until the user starts drawing next rectangle
let! down = Async.AwaitObservable(form.MouseDown)
let downPos = (down.X, down.Y)
if (down.Button &&& MouseButtons.Left) = MouseButtons.Left then
// Wait for the end point of the rectangle
let! upPos = drawingLoop(Color.IndianRed, downPos)
do printfn "Drawn rectangle (%A, %A)" downPos upPos }
This is a very imperative approach (in the usual pragmatic F# style), but it avoids using mutable state for storing the current state of drawing and for storing inital location. It can be made even more functional though, I wrote a library that does that as part of my Master thesis, which should be available on my blog in the next couple of days.
Functional Reactive Programming is a more functional approach, but I find it somewhat harder to use as it relies on quite advanced Haskell features (such as arrows). However, it is very elegant in a large number of cases. It's limitation is that you cannot easily encode a state machine (which is a useful mental model for reactive programs). This is very easy using the F# technique above.
Whether you're in a hybrid functional/OO language like F# or OCaml, or in a purely functional language like Haskell where side-effects are relegated to the IO monad, it's mostly the case that a ton of the work required to manage a GUI is much more like a "side effect" than like a purely functional algorithm.
That said, there has been some really solid research put into functional GUIs. There are even some (mostly) functional toolkits such as Fudgets or FranTk.
You might check out the series by Don Syme on F# where he demo's creating a gui. the following link is to third part of the series (you can link from there to the other two parts).
Using F# for WPF development would be a very interesting GUI paradigm...
http://channel9.msdn.com/shows/Going+Deep/C9-Lectures-Dr-Don-Syme-Introduction-to-F-3-of-3/
One of mind-opening ideas behind Functional Reactive Programming is to have an event handling function producing BOTH reaction to events AND the next event handling function. Thus an evolving system is represented as a sequence of event handling functions.
For me, learning of Yampa became a crucial poing to get that functions-producing-functions thing properly. There are some nice papers about Yampa. I recommend The Yampa Arcade:
http://www.cs.nott.ac.uk/~nhn/Talks/HW2003-YampaArcade.pdf (slides, PDF)
http://www.cs.nott.ac.uk/~nhn/Publications/hw2003.pdf (full article, PDF)
There is a wiki page on Yampa at Haskell.org
http://www.haskell.org/haskellwiki/Yampa
Original Yampa home page:
http://www.haskell.org/yampa (unfortunately is broken at the moment)
Since this question was first asked, functional reactive programming has been made a bit more mainstream by Elm.
I suggest checking it out at http://elm-lang.org , which also has some truly excellent interactive tutorials on how to make a fully functional in-browser GUI.
It allows you to make fully functional GUI's where the code you need to supply yourself consists only of pure functions. I personally found it a lot easier to get into than the various Haskell GUI frameworks.
Elliot's talk on FRP can be found here.
In addition, not really an answer but a remark and a few thoughts: somehow the term "functional GUI" seems a little bit like an oxymoron (pureness and IO in the same term).
But my vague understanding is that functional GUI programming is about declaratively defining a time dependent function that takes the (real)time dependent user input and produces time dependent GUI output.
In other words, this function is defined like a differential equation declaratively, instead of by an algorithm imperatively using mutable state.
So in conventional FP one uses time independent functions, while in FRP one uses time dependent functions as building blocks for describing a program.
Let us think about simulating a ball on a spring with which the user can interact. The ball's position is the graphical output (on the screen), user pushing the ball is a keypress (input).
Describing this simulation program in FRP (according to my understanding) is done by a single differential equation (declaratively): acceleration * mass = - stretch of spring * spring constant + Force exerted by the user.
Here is a video on ELM that illustrates this viewpoint.
As of 2016, there are several more, relatively mature FRP frameworks for Haskell such as Sodium and Reflex (but also Netwire).
The Manning book on Functional Reactive Programming showcases the Java version of Sodium, for working examples, and illustrates how an FRP GUI code base behaves and scales in comparison to imperative as well as Actor based approaches.
There's also a recent paper on Arrowized FRP and the prospect of incorporating side effects, IO and mutation in a law abiding, pure FRP setting: http://haskell.cs.yale.edu/wp-content/uploads/2015/10/dwc-yale-formatted-dissertation.pdf.
Also worth noting is that JavaScript frameworks such as ReactJS and Angular and many others either already are or are moving towards using an FRP or otherwise functional approach to achieving scalable and composable GUI components.
Markup languages like XUL allow you to build a GUI in a declarative way.
To address this I posted some thoughts of mine in using F#,
http://fadsworld.wordpress.com/2011/04/13/f-in-the-enterprise-i/
http://fadsworld.wordpress.com/2011/04/17/fin-the-enterprise-ii-2/
I'm also planning to do a video tutorial to finish up the series and show how F# can contribute in UX programming.
I'm only talking in context of F# here.
-Fahad
All these other answers are built up upon functional programming, but make a lot of their own design decisions. One library that is built basically entirely out of functions and simple abstract data types is gloss. Here is the type for its play function from the source
-- | Play a game in a window. Like `simulate`, but you manage your own input events.
play :: Display -- ^ Display mode.
-> Color -- ^ Background color.
-> Int -- ^ Number of simulation steps to take for each second of real time.
-> world -- ^ The initial world.
-> (world -> Picture) -- ^ A function to convert the world a picture.
-> (Event -> world -> world)
-- ^ A function to handle input events.
-> (Float -> world -> world)
-- ^ A function to step the world one iteration.
-- It is passed the period of time (in seconds) needing to be advanced.
-> IO ()
As you can see, it works entirely by supplying pure functions with simple abstract types, that other libraries help you with.
The most apparent innovation noticed by people new to Haskell is that there is a separation between the impure world that is concerned with communicating with the outside world, and the pure world of computation and algorithms. A frequent beginner question is "How can I get rid of IO, i.e., convert IO a into a?" The way to to it is to use monads (or other abstractions) to write code that performs IO and chains effects. This code gathers data from the outside world, creates a model of it, does some computation, possibly by employing pure code, and outputs the result.
As far as the above model is concerned, I don't see anything terribly wrong with manipulating GUIs in the IO monad. The largest problem that arises from this style is that modules are not composable anymore, i.e., I lose most of my knowledge about the global execution order of statements in my program. To recover it, I have to apply similar reasoning as in concurrent, imperative GUI code. Meanwhile, for impure, non-GUI code the execution order is obvious because of the definition of the IO monad's >== operator (at least as long as there is only one thread). For pure code, it doesn't matter at all, except in corner cases to increase performance or to avoid evaluations resulting in ⊥.
The largest philosophical difference between console and graphical IO is that programs implementing the former are usually written in synchronous style. This is possible because there is (leaving aside signals and other open file descriptors) just one source of events: the byte stream commonly called stdin. GUIs are inherently asynchronous though, and have to react to keyboard events and mouse clicks.
A popular philosophy of doing asynchronous IO in a functional way is called Functional Reactive Programming (FRP). It got a lot of traction recently in impure, non-functional languages thanks to libraries such as ReactiveX, and frameworks such as Elm. In a nutshell, it's like viewing GUI elements and other things (such as files, clocks, alarms, keyboard, mouse) as event sources, called "observables", that emit streams of events. These events are combined using familiar operators such as map, foldl, zip, filter, concat, join, etc., to produce new streams. This is useful because the program state itself can be seen as scanl . map reactToEvents $ zipN <eventStreams> of the program, where N is equal to the number of observables ever considered by the program.
Working with FRP observables makes it possible to recover composability because events in a stream are ordered in time. The reason is that the event stream abstraction makes it possible to view all observables as black boxes. Ultimately, combining event streams using operators gives back some local ordering on execution. This forces me to be much more honest about which invariants my program actually relies on, similar to the way that all functions in Haskell have to be referentially transparent: if I want to pull data from another part of my program, I have to be explicit ad declare an appropriate type for my functions. (The IO monad, being a Domain-Specific language for writing impure code, effectively circumvents this)
Functional programming may have moved on from when I was at university, but as I recall the main point of a functional programming system was to stop the programmer creating any “side effect”. However users buy software due to the side effects that are created, e.g. updating a UI.
if i like Ruby a lot, is there a reason I should learn another language now, such as Lua or Erlang?
New programming languages, much like spoken languages, can open up new perspectives. Learning new languages -- especially ones rather different from what you're used to (and Erlang will probably fit that bill) -- can teach you a lot of different things you didn't even know you didn't know about programming. So yes, I think you absolutely should, even if you just learn enough to tinker with it and get a feel for the new language.
Learning a functional language in particular can be extremely beneficial. Becoming familiar with the functional style of programming is a surefire step toward becoming a better programmer. Lisp (or its derivatives) in particular is a good language to study. Here's a list of past thread on SO that might offer you some insight along these lines:
Why do people think functional programming will catch on?
What’s a good Functional language to learn?
Benefits of learning scheme?
Leaving aside the (excellent) general reasons to want to learn another language, if you like Ruby a lot you might want to
Learn Smalltalk, which is a language very, very similar to Ruby but in purer form.
Learn a language that is very, very different—say something that is based on algebraic data types and functions rather than objects and methods, and something with a static type system rather than a dynamic type system—but something that, like Ruby, will support powerful methods of program composition and generic programming. Good candidates would include Standard ML and Haskell.
Learn a language that is very, very different—say something that makes you control every bit, address, and word in memory—something that forces you to understand and take control of the hardware. In other words, learn C.
Regarding the other languages you mention,
Lua is small and very elegantly designed and implemented. That may appeal to the Rubyist in you. But unlike Ruby it does not impose much of a worldview; it is more of a collection of piece parts. I would suggest you're more likely to appreciate and enjoy Lua after you've worked in three or four other languages first.
Erlang is interesting, but I have a gut feel it's either too different (purely functional, distributed) or not different enough (dynamic type system). But if it appeals to you, go for it.
On the other hand, there's something to be said for really knowing a language well. You'll be able to do a lot more with in-depth knowledge of a single language than you will with surface knowledge of a dozen.
If you like Ruby a lot you should definitely learn another language... one without sigils if possible.
Seems to me that a professional learns the tools he needs to use. Frameworks, containers, languages, all are fair game. I started out in Pascal, went to C and then C++. Then converted to Java. These days its mostly Java with a lot of Javascript and some PHP. Easy enough right? Well, I also need to learn Bash scripting and Perl. Never mind all the other crap I need to get on top of (if you say you understand all of web authentication I will call you a liar). There's a lot of stuff out there. Jump in. Be willing to try different things.
I always enjoy learning new languages for the mere challenge of it. It keeps my brain fit. I've also found it makes for good job interview fodder to be able to say "I'm flexible. I'm adaptable to whatever your needs may be in the future. And I can prove it with my long list of languages."
My main language is PHP. I am a script language fan, nevertheless I have dived into C#, Java, Python, Ruby and even OO JavaScript books to find new mechanisms, ways of thinking. I have found pretty many stunts in Java for example, that I could implement in my all day work. So learning or just studying new languages can widen your perspective.
I've just started one of my courses, as classes just began 2 weeks ago, and we are learning Scheme right now in one for I assume some reason later on, but so far from what he is teaching is basically how to write in scheme. As I sit here trying to stay awake I'm just trying to grasp why I would want to know this, and why anyone uses it. What does it excel at? Next week I plan to ask him, whats the goal to learn here other than just how to write stuff in scheme.
It's a functional programming language and will do well broaden your experience.
Even if you don't use it in the real world doesn't mean it doesn't have any value. It will help you master things like recursion and help to force you to think of problems in different ways than you normally would.
I wish my school forced us to learn a functional programming language.
Languages like LISP (and the very closely related Scheme) are to programming what Latin is to English.
You may never speak Latin a day in your normal life again after taking a course, but simply learning a language like Latin will improve your ability to use English.
The same is true for Scheme.
I see all these people here saying that while they would never actually use Scheme again it's nevertheless been a worthwhile language to learn because it forces a certain way of thinking. While this can be true, I would hope that you would learn Scheme because you eventually will find it useful and not simply as an exercise in learning.
Though it's not blazingly fast like a compiled language, nor is it particularly useful at serving websites or parsing text, I've found that Scheme (and other lisps by extension) has no parallel when it comes to simplicity, elegance, and powerful functional manipulation of complex data structures. To be honest, I think in Scheme. It's the language I solve problems in. Don't give up on or merely tolerate Scheme - give it a chance and it won't disappoint you.
By the way, the best IDE for Scheme is DrScheme, and it contains language extensions to do anything you can do in another language, and if you find something it can't you can just use the C FFI and write it yourself.
I would suggest to keep an open mind when learning. Most of the time in school we don't fully comprehend what/why we are learning a particular subject. But as I've experienced about a million times in life, it turns out to be very useful and at the very least being aware of it helps you. Scheme, believe it or not, will make you a better programmer.
Some people say Scheme's greatest strength is as a teaching language. While it is very beneficial to learn functional programming (it's an entirely new way of thinking) another benefit in learning scheme is that it is also "pure". Sure it can't do a ton of stuff like java, but that's also what's great about it, it's a language made entirely of parentheses, alphanumeric characters, and a mere handful other punctuations.
In my intro course, we are taught Java, and I see lots of my friends struggling with 'public static void main' even though that's not the point of the program and how the profs have no choice but to 'handwave' it until they're more advanced. You don't see that in Scheme.
If you really want to learn what Scheme can do in a piece of cake that is really hard to implement in languages like Java, I suggest looking at this: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-12.html#%_sec_1.3
This is probably the best book written on Scheme.
Scheme was used by NASA to program some of the Mars rovers. It's usage in the marketplace is pretty specific, but like I'm sure your teachers are telling you, the things you learn in Scheme will carry over to programming in general.
Try not to get caught up on details like the parenthesis, and car/cdr. Most of what you're learning translates to other languages in one way or another. Don't worry about whether or not you can take Scheme to the market place, chances are you'll be learning some other more marketable languages in other classes. What you are learning here is more important.
If you are learning scheme, you can learn all about how object systems are implemented (hint: an object system isn't always about a type that has methods and instance variables bound to it...). While this kind of knowledge won't help in 95% of your daily work, for 5% of your work you will depend on that knowledge.
Additionally, you can learn about completely different styles of computation, such as streams/lazy evaluation, or even logic programming. You could also learn more about how computer programs in general are interpreted; from the basics in how program code is evaluated, to more deeper aspects like making your own interpreter and compiler). Knowing this kind of information is what separates a good programmer from a great programmer.
Scheme is not really a Functional language, it's more method agnostic then that. Perhaps more to the point, Scheme is an excellent language to choose if you want to explore with different methods of computation. As an example, a highly parallel functional language "Termite" was built on top of Scheme.
In short, the point in learning scheme is so that you can learn the fundamentals of programming.
If you need some help in making programming in scheme more enjoyable, don't be afraid to ask. A lot of programmers get hung up on (for instance) the parenthesis, when there are perfectly great ways to work with scheme source code that makes parenthesis something to cherish, rather then hate. As an example, emacs with paredit-mode,some kind of scheme interaction mode and highlight-parenthesis-mode is pretty awesome.
My problem was when learning this we learned clisp right along with it. I couldn't keep the two strait to save my life.
What I did learn from them though was how to write better c and java code. This is simply because of the different programming style I learned. I have adapted more of the functional style into some of my programming and It has helped me in some cases.
I would never want to program in scheme or lisp again if I didn't have to, but I am glad that I at least did a little in them just to learn the different way to program.
Functional languages like Scheme have great application to mathematics, artificial intelligence, linguistics, and other highly theoretical areas of computer science (machine learning, natural language processing, etc). This is due to the purity of functional programming languages, which have no side effects, as well as their ability to navigate higher-order procedures with ease. A strong knowledge of functional programming languages is critical for solving many of the questions which hover just beyond the frontier of computer science. As a bonus, you'll get great with higher-order procedures and recursion.