Why should non-CS majors learn functional programming?

July 31, 2015 at 7:40 am 17 comments

In my research, I’m most interested in the non-CS majors, the ones who learn computing because it makes them more productive (see where I make that argument) or because they want to make themselves more marketable (see Eric Robert’s post) or because they will live and work (as I predict) in the fat line between programmers and users (see post here).  A recent article in the CACM suggests that all non-CS majors need to be learn (let’s not use the “be exposed” euphemism — there’s no sense in “exposing” someone to something unless you’d like them to learn from it) “functional programming languages [and] the declarative programming paradigm.”  I’m willing to consider that, but why?  The quote below says, “they allow programmers to do more with less and enable compilation to more efficient code across a wide range of runtime targets.”  I’ve been studying non-CS majors who program for a lot of years, and I’ve never heard any of them say even once that they want to “enable compilation to more efficient code across a wide range of runtime targets.”

So let’s consider the “more with less.”  Do we buy that what what non-CS majors is to be able to get more expressive power with fewer keystrokes?  I don’t see the argument for that.

  • Brian Dorn studied graphic designers who program, and found that assignment was fairly hard for them to learn (see his CHI 2010 paper).  Surely, there’s not much that has fewer characters than that.
  • Neil Brown has been mining the BlueJ Blackbox data for empirical data on what students get wrong most often (see his ICER paper).  I was surprised to learn that confusing & for && and | for || is pretty common.  Those are pretty easy to type, short, and seemingly error-prone expressions.
  • We have Thomas Green’s fascinating result that that IF P THEN … END P; IF NOT P THEN … END NOT P. is not just better than IF P THEN…ELSE.…  It’s ten timebetter — novices do better by a magnitude if they avoid ELSE.

My suspicion is that non-CS major programmers value understandability and fewer errors, over fewer keystrokes and more power.

I like functional programming and would be interested in a good argument for it for non-CS majors.  I don’t see it here.

Second, would-be programmers (CS majors or non-majors) should be exposed as early as possible to functional programming languages to gain experience in the declarative programming paradigm. The value of functional/declarative language abstractions is clear: they allow programmers to do more with less and enable compilation to more efficient code across a wide range of runtime targets. We have seen such abstractions gain prominence in DSLs, as well as in imperative languages such as C#, Java, and Scala, not to mention modern functional languages such as F# and Haskell.

via Teach Foundational Language Principles | May 2015 | Communications of the ACM.

Entry filed under: Uncategorized. Tags: , , , , , .

How to Learn Computer Programming Efficiently through Computer Games: Michael Lee and Gidget Why we are teaching science wrong, and how to make it right: It’s about CS retention, too

17 Comments Add your own

  • 1. iamleeg  |  July 31, 2015 at 8:00 am

    > Brian Dorn studied graphic designers who program, and found that assignment was fairly hard for them to learn (see his CHI 2010 paper).

    An anecdatum: I used to teach programming to physics UGs and saw this, and heard similar from people teaching programming to engineering UGs. The underlying problem we found was that “x = 3” looks like an _equation_, something that will always be true. That makes “x = x + 1” paradoxical and also means that ordering of equations should be unimportant.

    Addressing that difficulty (which shouldn’t be done in isolation, but anyway) is the spreadsheet, where relations _do_ hold.

    Reply
  • 2. dennisfrailey  |  July 31, 2015 at 8:59 am

    In every field of study and every specialty within a field of study there are concepts or techniques that specialists find to be so beautiful or special or powerful (or whatever) that some of them wish the greater, non-specialist community would learn about them. Whether it be the Shakespearian schoilar who wants every schoolchild to read something of Shakespeare or the physicist who wants every college student to learn about string theory or the archaeologist who wants them all to learn something or other, the phenomenon is widespread and computer scientists are no different. There are the AI specialists who want everyone to learn LISP, the functuional programming advocates who want them all to learn functional programming, and of course the many who want everyone to learn progrmamming (although the debate over which language continues). I, for one, think all educated people today should learn about computability and completeness, not to mention the Blum speedup theorem. But few people today have the time, money or interest to become as well educated as it would take to learn all these things. I understand the charms of functional programming but doubt that it will ever be more than a minor curiosity for anyone outside the field of computer science.

    Reply
  • 3. Brian Harvey  |  July 31, 2015 at 9:28 am

    Because it’s beautiful, and we want students to see programming as interesting in itself, not just instrumentally. Assignment and looping just aren’t beautiful, and the designers of those imperative languages seem to be /trying/ to make them ugly, using = as the assignment operator, and then doubling down in C and its children by turning the assignment statement into an assignment /expression/, so we have to explain why 3+x=5 has the value 8 when anyone can see that the answer is 2.

    Besides, one of the pedagogic virtues of programming is that it’s a second chance for students who think they hate math, and functional programming does a better job of promoting formal reasoning. (We don’t put it to students in those terms; that would scare some of them away.)

    Reply
  • 4. Martijn Stegeman  |  July 31, 2015 at 9:37 am

    Anecdotally, functional programming has particularly influenced my my decomposition skill.

    I’d argue that making small functions, giving them names, thinking about this way of abstracting does help you create simpler abstractions which helps you (me) feel more confident in having a correct mental model of your programs. This confidence seems to be a positive effect, but you may be able to gain this kind of confidence in other ways, of course.

    Other than that, the question is also: would non-majors benefit from understanding programming languages better? Functional programming has often been used to explain core programming concepts and differences between paradigmas, which helps you understand the limits of your language, for example. Could be or not be useful.

    All of this seems to be part of a reflective step that could arguably be expected in any academic course (but it still goes back to the question of how much CS there should be, and of what kind, in non-major courses).

    Reply
  • 5. Ben Zorn  |  July 31, 2015 at 1:44 pm

    Mark, thanks for referring to our article. I really appreciate your well-informed perspective on the needs and goals of non-CS majors that want/need to program. I think that increasing many people across industries will benefit from a basic understanding of programming, as is supported by the efforts of code.org.

    In terms of the comments in the paper, I have a few thoughts. First, I agree with you the everyone’s goal in writing a program is to get the job done as quickly and effectively as possible. As a result, languages the provide abstractions closer to the problem domain are generally much more attractive to use. The R language is an excellent example of this – it combines language features that provide intuitive operations on data with a collection of libraries that make many common tasks available without any programming at all.

    So, in terms of the “more with less” my perspective is that functional/declarative high-level domain-specific languages make programs easier to write and make it more likely your program will be correct when you are done. Functional languages provide mechanisms and abstractions (like lambda expressions and isolating side effects) that make composition easier and strong typing allows early feedback that programs have errors. Increasingly with parallel and client-server computing, having language support for controlling side effects will lead to simpler and more correct programs.

    In terms of easier compilation to targets, it is true the most novices don’t think about the efficiency of their programs. However, just because they don’t initially think of these things does not mean they aren’t important. In the world of cloud computing and big data, thinking about the cost of training a machine learning model is important because cycles cost money. At some point, people using these models or building them have to understand something about the cost of executing the programs. One of the reasons that SQL is widely used is because it hides the very powerful optimizations that happen to queries entirely from the programmer. So, as we say in the paper, you get an expressive language with fast execution across targets. I think SQL is a good example that justifies our comments on both points.

    Reply
    • 6. Mark Guzdial  |  July 31, 2015 at 10:33 pm

      Thanks for responding, Ben! That non-CS majors would be able to write code with fewer errors, with less effort (perceived? timed?) would certainly be a benefit. Those are empirical claims that we should be evaluate. I know that some language paradigm comparisons are difficult because it takes so much time to develop expertise in a paradigm. But with non-CS majors, we don’t expect the development of expertise (at least, to the level of professional software developers). We should be able to test those claims.

      Reply
      • 7. Kathi Fisler  |  August 1, 2015 at 6:22 am

        I am actively working on cross-paradigm comparisons (currently with first-year programming students). We’re taking a collection of programs that have been vetted by both functional-first and imperative-first proponents, giving them to multiple classes in each paradigm, and seeing whether any differences jump out.

        Data analysis is ongoing, but we are seeing some differences in how students structure their code (which impacts the errors that they either set themselves up to make or do make), as well as how students perceive different solutions to these problems. Many of these differences appear to tie to the libraries and built-ins that students have learned: functional and imperative courses tend to teach different programming patterns (no surprise), and these patterns suggest different structures of code (again no surprise). This doesn’t yet lead to a value judgement between paradigms, but it does help us start to poke at where differences might be coming from, and which might be inherent to one style or the other.

        I’ll have a poster at ICER next week that previews our work on this.

        Kathi

        Reply
    • 8. Thomas Ball  |  August 1, 2015 at 8:31 pm

      Adding to Ben’s point, our recommendations to educators were based on trends we observe in industry rather than studies of students. It would be wonderful to have more empirical evidence for the functional approach!

      The advance of functional paradigms for data processing languages in industry is quite clear (SQL being the standard bearer) as well as the number of positions in industry for people to perform data analysis – for which I imagine many non-majors would be suited.

      In analyzing evidence, we should also be careful to separate out the various kinds of languages, as referenced in our article: domain-specific languages, general purpose languages, etc. SQL is a domain-specific language that I imagine many non-CS majors end up learning after college as they enter the business world. Our focus on the functional/declarative paradigm in the article was pointedly on domain-specific languages. In industry, the imperative approach still dominates for general purpose languages.

      Nonetheless, there has been increasing adoption of general purpose functional languages in industry over the last decade, and it should be possible to study the tradeoffs between function and imperative approaches in industry as well as the classroom. This can be done even within one general purpose language. For example, C# added a SQL-like sublanguage (LINQ) that is widely used. It makes use of lambdas and function compositional heavily.

      Reply
  • 9. Errol Thompson  |  July 31, 2015 at 4:13 pm

    Mark,

    I have been increasing trying to identify the thinking that each of the programming paradigms encourage. I see Martjin in his post talks of how he perceives an improvement in his decomposition ability. The more I try to understand the thinking patterns for each paradigm, I would agree that functional programming would improve decomposition but is there more about the functional programming way of doing things?

    There is also a school of thought that says functional programming is a more sound base for being able to develop the generic programming skills. Once someone understands the use of functions to create a programs, they will find it easier to write both imperative and object-oriented code. Does functional programming lead to better understanding of recursive data structures as well?

    It seems to me that we focus too much on the programming when it is really the thinking and problem solving skills required to produce a program that is really the transferable skill. Can non-programmers use these skills to solve problems in their own domains? I believe this is what Jeanette Wing was arguing when she promoted computational thinking.

    Reply
    • 10. Mark Guzdial  |  July 31, 2015 at 10:34 pm

      That kind of transfer of problem-solving skills is exactly what the educational psychologists I worked with in Germany find unlikely: https://computinged.wordpress.com/2015/07/13/growing-cs-ed-through-schools-of-ed-report-from-oldenburg/

      Reply
      • 11. Errol Thompson  |  August 1, 2015 at 4:08 pm

        I might actually agree with the argument that learning computing isn’t going to help if you define learning the computational thinking skills only in the context of computing. Focusing on the thinking skills behind the imperative paradigm, how does it help someone with understanding music or business processes? Using an object-oriented paradigm as interacting entities, how could it help someone with understanding business organisations or sports teams or …? Using the functional paradigm, how does it help identify abstractions or …? How do the principles are the principles of abstraction, encapsulation, … applied to different aspects of life? Do we ask these questions and foster this style of thinking in our students? To me this is the challenge of teaching computational problem solving. Programming or the computational representation of a solution is a byproduct of this process and not the central objective. Maybe, we should ask the students to develop their own representation given the computational thinking ideas rather than trying to have them conform to those already defined.

        Let’s talk about problem solving in a computational context then if we start with a problem then the first step is understanding the problem. What are the techniques that can be applied to that before we actually begin thinking about programming? When I worked in industry, I found that often what people were asking to be programmed was changed once we endeavoured to understand the problem in a computational way. Sometimes this led to not producing a program at all.

        There is another issue that I have with this none transfer between domains. As I understand it the best innovators actually used concepts from one domain to think about problems in another domain (sorry can’t remember the reference right now). What we tend to do with modern education is narrow the field of study so that there is little or no cross fertilisation between disciplines. Synthesising ideas from different fields or sub-fields is a cognitive skill. Do we expect it from our best students? Personally, this is where my best ideas come from.

        Just for the record,I am a nonconformist and I endeavour to do what people tell me can’t be done. Hence as a computer scientist and educational researcher, I am seeking to foster conceptual change in economics as a road to peace building. I will draw on at least three disciplines in my work. Shouldn’t we be fostering this type of thinking?

        Reply
  • 12. Alan Fekete  |  August 2, 2015 at 4:05 am

    I think there is an important distinction between A) what one should teach about computing if one is teaching it to every student (something Mark has been advocating for so long in this blog and elsewhere, and where we must really justify the time we claim in the curriculum, especially justify it to profs from every other discipline that does not have the same share), and B) what one should teach in an elective for non-majors (where the students have chosen to study some computing, and we only have to justify the content to the students, not to other professors).

    For the latter case (an elective), traditionally the view was what Brian Harvey described in comment 3: show them some beauty in the big ideas of the discipline. Recently however, student numbers have skyrocketed for CS in many R1 unis in the USA, probably because of the view that software is eating the world, and students want to have the skills to be predator not prey! That is, the student influx is driven by utilitarian motives, and the students may well be unhappy or resistant if what they learn is beuatiful but it doesn’t help them get a great summer job or internship, or an assistantship in a professor’s lab in their intended major (after just one CS subject!). My own view is that one semester of functional programming isn’t nearly as much utility as one semester of Python, for getting a foot in the door as a programmer.

    Reply
  • 13. fgmart  |  August 2, 2015 at 9:57 am

    Seems like the thrust of the essay was about what CS majors should learn. Perhaps the authors’ comment about non-majors too was somewhat accidental. They definitely didn’t justify it in the essay 🙂

    Reply
  • 14. orcmid  |  May 3, 2019 at 5:01 pm

    Where can I find “Thomas Green’s fascinating result?” I agree, the preference seems to be an argument for by cases. That’s not surprising. There are nasty edge cases in the IF p then … end; If not p then … end; that will not be recognized by beginners though and there are valuable considerations for not evaluating p twice :)..

    Reply
    • 15. orcmid  |  May 3, 2019 at 5:29 pm

      So learning to cover the bases and seeing the bases covered works for something like

      case p
      of true: mumble
      false: more_mumble

      where either mumble could be “continue” ?

      That is in a statement language. In an expression language “continue” doesn’t work and if p then mumble else other_mumble is pretting natural.

      Since covering the bases is computational thinking, I daresay, how does one found this in a learning-curve progression?

      Reply
    • 16. Mark Guzdial  |  May 3, 2019 at 9:43 pm

      Series of papers by M.E. Sime and T. R. G. Green in the 1970’s.

      Reply
    • 17. Mark Guzdial  |  May 3, 2019 at 10:08 pm

      Green summarizes a bunch of this work in: Green, T. R. G. “Programming as a cognitive activity.” Human interaction with computers (1980): 271-320.

      Reply

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Trackback this post  |  Subscribe to the comments via RSS Feed


Enter your email address to follow this blog and receive notifications of new posts by email.

Join 11.4K other subscribers

Feeds

Recent Posts

Blog Stats

  • 2,096,527 hits
July 2015
M T W T F S S
 12345
6789101112
13141516171819
20212223242526
2728293031  

CS Teaching Tips