Task-specific programming languages: People aren’t dumb. Programming is hard.

March 25, 2019 at 7:00 am 22 comments

I’ve been thinking a lot about task-specific programming languages lately.  I’m inspired by the work on domain-specific programming languages (e.g., see blog post here), and have been wondering whether we can reduce the cognitive load even further by focusing on programming languages for specific tasks. I’m thinking that we should be applying HCI design techniques (e.g., user centered design) and apply them to the design of small, task-specific programming languages.

But that got me wondering: Surely this is not a new idea.  What do we know about task-specific programming languages? Do students learn generalized ideas about programming from learning a task-specific programming language? How does it change affect or cognitive load if students start with a programming language tuned especially to their task?

I did some literature searches, and found a highly relevant paper: “Task specific programming languages as a first programming language.”  And the lead author is…me.  I wrote this paper with Allison Elliott Tew and Mike McCracken, and published it in 1997.  I honestly completely forgot that I had written this paper 22 years ago. Guzdial-past knew things that Guzdial-present does not.

The paper doesn’t answer any of my questions.  It talks about some surveys and comparisons we were doing, but offers no results.  I have no idea where the data from those surveys and comparisons are today.

Abstract: This research investigates whether there is a difference in the acquisition of programming skills and knowledge as a function of a student’s first language. Our research is concerned with the comparison of task specific languages and general programming languages. In many engineering programs students are first exposed to the principles of computational solutions to problems by means of task specific languages, such as MatLab. They are then either expected to be able to use, or are specifically taught programming using more general purpose languages, such as C. Our question is whether there is a developmental preference for learning a task specific language first, or a general purpose language first. Historically, educators have emphasized fundamentals prior to application. A case could therefore be made that a student should be taught general programming skills in the context of a general purpose language before solving problems in a task specific language. More recently, contextualized educators would prefer the initial learning of task specific languages. Our research anticipates answering the question of the effectiveness of transfer of programming skills as a function of first language learning. The dimensions of this question include but are not limited to, how the languages are used, what types of problems are presented to the students, is transfer prompted between the languages, do students look for surface or structural similarities, and what are the assumptions and expectations of the faculty who teach these languages.

Here’s my favorite paragraph in the paper. Yup, still have all those same questions.

We have developed a comparison of task specific languages and general purpose languages to allow us to investigate ontological boundaries between languages and their impact on transfer. For example, MatLab essentially has no typing. It uses built in types. Whereas, general purpose languages have various types, including enumerated types, and support the construction of complex data structures around those types. Does this difference cause a boundary to transfer? If a student learns MatLab first, will data types be more difficult to learn? If a student learns a general purpose language first, will they be able to transfer their skills to a language that prevents them from constructing many of the structures they have previously used?

I’m still catching up on podcasts that I missed during my move.  One of those was a rebroadcast of an interview with Richard Thaler, one of the founders of behavioral economics and a recent Nobel prize winner in Economics.  He explains the central idea of behavioral economics: “People aren’t dumb. The world is hard.”

So, we don’t think people are dumb. We think the world is hard. I mean, figuring out how much to save for retirement is a really hard cognitive problem that very few economists have solved for themselves. And it’s not only cognitively hard, it involves delay of gratification, which people find hard. It’s just like navigating in a strange city is hard. So, why not try to help? When I first was working with the U.K. Behavioral Insight Team, the first “Nudge unit,” the phrase I kept saying in every meeting with some minister was, “If you want to get people to do something, make it easy. Remove the barriers.” That’s what we’re about.

If we want people to program, make it easy. Remove the barriers. That’s what we’re about. People aren’t dumb. Programming languages are hard.  If we can fix that, we should. That’s what I see task-specific programming as being about.

 

Entry filed under: Uncategorized. Tags: , .

Where to find Guzdial and Ericson Web Resources post-Georgia Tech: Bookmark this post Using MOOCs for Computer Science Teacher Professional Development

22 Comments Add your own

  • 1. Neil Brown  |  March 25, 2019 at 7:07 am

    This paper about domain specific language comprehension may be of interest: https://link.springer.com/article/10.1007/s10664-011-9172-x What is the difference between domain specific languages and task specific languages? Could you give an example of a language you consider domain specific, and one you consider task specific?

    Reply
  • 2. alanone1  |  March 25, 2019 at 7:37 am

    Hi Mark

    I think “the world is hard” and “programming is hard” obtain whether or not “humans are dumb” (I think we are — which makes things even tougher).

    To me, (a) the shape of a programming language is a key part of its user interface, and (b) all programming languages are rather more task specific than not.

    Key features of a programming language are how well it matches to particular tasks; how well within “domains”; how well for random needs, etc.

    There’s another level that is worth pondering: how easy is it — how well does the result turn out — to try to make a task-oriented “region” within a particular language?

    This was one of the big interests in “high level computing” in the 60s. This is partly asking “how meta and in what areas” is my programming language? The assumption here is that the “TOL” will be shaped by experts and not in a few hours, but in a week or two.

    Lisp, of course, shows up here, and can be shaped quite well (and especially with some good tools like those “LISP 70” had).

    Another system in which a lot could be done was Ned Irons’ IMP language — one could make many special languages with both nice forms and efficient execution.

    Smalltalk-72 was quite good at this also (not as much the later Smalltalks — though the Lisp comments above apply here also).

    The languages that were much less successful were the ones that were specifically task-oriented. This is because it is very hard to anticipate the ranges of most real tasks — so systems — such as IBM’s RPG, etc. — could be very frustrating to use: they lacked customization features to deal with unanticipated needs.

    One way to think about this is that computers are about unlimited degrees of freedomprogramming is about shaping those degrees of freedom, and a big mistake is to remove too many degrees of freedom, rather than trying to figure out how to tame them.

    A simple (but enormously large) set of examples of how ->NOT<- to go about things is to examine the UIs and facilities in most personal computing systems today, including the web browser, and mobile phones and apps.

    Reply
  • 3. Andy Rundquist  |  March 25, 2019 at 7:40 am

    I have always leaned toward teaching task-specific languages first (I’m a physics professor so I’m typically talking about physics majors here). One reason is that they’re goal is to either model something (and so having built-in graphics capabilities or differential equation solvers is handy) or affect something in the real world (so built-in instrument drivers is handy). Admittedly for many of my students those are the only two things I want them to do but as I reflect on the students who move on to more programming, it seems that they make the transition to more general programming languages decently well, especially when they see the ability to do things like making complex data structures. Certainly my own journey worked in that order.

    I echo Neil Brown’s question about the difference between domain- and task-specific languages. My guess: They are actually pretty much the same, ie Matlab, LabVIEW could be considered either. Perhaps Mathematica is neither? Would you consider something like imageJ to be either?

    Reply
  • 4. Mark Guzdial  |  March 25, 2019 at 10:13 am

    I respond to Neil, Alan, and Andy in this one comment. I need to start out saying that this is a new direction for me — I’ve only been working on it over the last few months here at University of Michigan. I do not have a definition yet that I can rigorously defend.

    I do have that article, Neil — thanks! The empirical evidence on the value of domain-specific programming languages is a motivation for my work.

    Examples of Task-Specific Programming Languages that I think a lot about are Helena from Sarah Chasins for Web scraping (about which I plan a blog post in a few weeks) and Vega-Lite for data visualizations which we just used in a participatory design session with social studies teachers on 12 March. These are both programming languages designed for specific tasks. I’m not sure that they’re Turing Complete, and I suspect that that’s a key part of the definition. It’s notable that both of these languages also make a lot of effort to have an excellent user interface — the language is tuned to the task, and the interface is tuned to the user engaged in the task.

    Alan points out exactly the other issue that I’ve been thinking about: “regions” within existing programming languages.

    • The subset of Racket used in Bootstrap: Algebra is a great example. The Racket folks have also been building “language levels” which form fences around the regions — not walls, because it’s possible to get out of the level.
    • The subset of Scratch used by most children is in some sense a region. Scratch is already a domain-specific language (designed around the activities in the Computer Clubhouses), but what students actually do with Scratch forms a much smaller “region” of the language.
    • In the cited paper, I was exploring the idea of MATLAB (a domain-specific language) which is often used as a super-powerful programmable calculator (task-specific) by most Engineers and Engineering students.

    The advantage of a “region” approach is (a) there’s still a fuller, richer programming language to grow into yet (b) the notional machine is much smaller and more learnable for that region (like a task-specific programming language). You don’t have to know all of Scratch to use Scratch just for story-telling (the most common use).

    Yes, Andy, I see MATLAB, LabVIEW, R, and Mathematica as all domain-specific languages. While not in my area of research right now, I wonder what the implications are for domain-specific languages that grow into new tasks. R was originally designed for statistics and visualization. It was not designed to be a general-purpose language. Now it’s used for web-scraping and even making video games (!). What are the implications for learning when the notional machine gets extended in ways beyond what the designers intended?

    Where I’m at in my research: As suggested above, we just ran a participatory design session where we had social studies educators build a visualization in each of a general-purpose programming language (JavaScript with Google Charts service) and Vega-Lite, then had a focus group about what they value in these languages and what they would want in a programming language for their classes. I have the wireframe of a logic programming language for history classes (thinking about Alan’s comment about the “the shape of a programming language”). And I have students building components (like what we did around visualization) to do participatory design sessions with pre-calculus teachers. As we’re doing this, I’m trying to be reflective and take notes on how we’re doing things. My suspicion is that the design process for a task-oriented programming language is going to look a lot like a design process for a task-oriented user interface. In the end, the programming language is part of the user interface.

    Alan, could you say some more about this comment:

    To me, (a) the shape of a programming language is a key part of its user interface, and (b) all programming languages are rather more task specific than not.

    I think that (a) is about the idea of designing the programming language as part of the user interface. Is (b) the idea that, in actual practice, most programmers just use a small task-oriented part of the language?

    Reply
    • 5. alanone1  |  March 25, 2019 at 12:20 pm

      Hi Mark

      There is a bit of a “schmoosh” conflict between “learning programming” and “using a subset for some specific task” (you mentioned the use of Scratch for story telling).

      I think of the latter as “putting frets on a violin” or “training wheels on a bike” — in both cases you are not going to be learning what these things were before before the bad subsetting was done. However, you will get “notes” and “movement” respectively (and also the fantasy of being a violin player or bike rider — this is a big deal, especially in the US these days).

      We can see very similar tendencies with regard to “programming for all” — “success” is valued over “real success”. There’s sympathetic magic for many in just touching the stuff.

      As I tried to point out in my first comment, I think quite a bit has to be done to create examples that don’t overwhelm, but where one is still “in the middle of a whole city” where lots of things can be seen, not all of which are understandable right off the bat. The simplest heuristics I know for all this — and its strong overlap with UI — is to (a) first deal with cognitive load, but (b) without blanking out the context.

      (Using Scratch for story telling is not a good approach if the goal is to help a kid learn programming — it could be good for learning about story telling, but I don’t think that’s the topic here.)

      You say: Alan, could you say some more about this comment:

      *Alan: To me, (a) the shape of a programming language is a key part of its user interface, and (b) all programming languages are rather more task specific than not.

      Mark: I think that (a) is about the idea of designing the programming language as part of the user interface. Is (b) the idea that, in actual practice, most programmers just use a small task-oriented part of the language?*

      (a) The form of language is its intrinsic user interface, and there can be UIs built around this to provide even more scaffolding (especially for helping to visualize dynamically the consequences of various parts).

      (b) one way to think about this is to make a matrix of (say) 20 different programming styles/domains/problems vs. 20 languages and ask how much (and what kind of) work has to be done to get each language to allow a certain approach. Most languages will only fit a few of these, and most will require quite a bit of work to be set up for some of the styles (e.g. making a whole new language from the existing one).

      Reply
      • 6. Mark Guzdial  |  March 25, 2019 at 4:44 pm

        Hi Alan,

        I’m thinking a lot about the Katie Rich et al. papers on learning trajectories for dealing with that schmoosh conflict. I think students learning Scratch to do story-telling are still learning the first steps in those learning trajectories, ideas like “Different sets of instructions can produce the same outcome” and “The order in which instructions are carried out can affect the outcome.” I even have hope that those basic, fundamental ideas of how programming works do transfer.

        Your heuristics make a lot of sense to me — thanks!

        Thanks for the explanation of the comment. I don’t know how to think about the form of the language as an intrinsic user interface yet. The matrix idea does make clear what you mean by the programming language being task-specific. I have to think some more about how to measure that “fit” between a language and a style/domain/problem.

        Reply
        • 7. alanone1  |  March 26, 2019 at 12:36 am

          Hi Mark

          Well, one could say the same for BASIC for manifesting a few important ideas about programming (and also being powerful enough to make interpreters for any computer/language).

          My point was quite different. What I was driving at was that — taking BASIC as an example — if one ingested “typical BASIC” as “typical programming” (and this is what most do and did) — then one’s view and skills regarding programming is severely limited (despite the Turing completeness of the language).

          The “typical” is just too far away from “what is actually needed”, and what one does learn produces hardened barriers for other kinds of — much better — approaches.

          As for “intrinsic UI”, consider the UI of assembly code vs the UI of HyperTalk vs the UI of Lisp vs the UI of Java vs the UI of … Python?

          Reply
          • 8. Mark Guzdial  |  March 26, 2019 at 9:44 am

            Thank you, Alan. That helps me think through what’s needed in a task-specific programming language for education. I’m working on a blog post on this theme. More later.

            Reply
  • 9. Raul Miller  |  March 25, 2019 at 11:27 am

    Your phrasing here reminds me of the Mattel Barbie ‘math is hard’ meme and the public reaction to that (though wikipedia says that the actual quote was “math class is tough”).

    Anyways… thinking about what I have found hard, in programming:

    1) Getting started. For example, until I worked through a “Hello World” program in C, I was not able to recognize what the books I had been reading had omitted (presumably because the authors thought that those details were common knowledge or outside of scope or something).

    2) Absorbing the language’s abstractions. Spending a half hour a day over a period of years, trying things out and then sleeping on them has been my most successful approach here.

    3) Bogus documentation. All too often, how things actually work are different from what was described.

    Personally, I have done best with technical documentation that was mostly reference (syntax and definitions) with some accompanying tutorial and example works. Learning still takes time, but it takes much longer without those resources. Also, this assumes I’m in an environment where I can try things out.

    When I can’t try things out, I’ve found that what I learned is often silly interpretations that I can’t put to use. (And, looking back, I suspect some of my good grades in some classes must have had some of this character. But since I mostly only retain knowledge where I’ve tried it out, maybe that’s a partially self correcting issue.)

    Looking at things, today: programming is often hard because the problems people were working on are not the problems I need to solve. So I have to adapt code systems to work in the situations I’m faced with. Sometimes what I have to do seems just real stupid. (But, if it works, that at least lets me get on to the next issue…).

    Perhaps also worth noting here that computers tend to be really fragile. Most storage systems only last a few years. Computers don’t deal well with water (especially salt water). Malware has been a thing for decades (ever since the Morris Worm, possibly earlier in less harmful forms).

    So, yeah… it’s hard. But it’s best to address the issues that make it hard using approaches that other people have found useful… (as opposed to making it “easy” in some superficial fashion while actually making it more difficult – we have plenty examples of that to work with, also).

    Reply
  • 10. Mark L Miller PHD  |  March 25, 2019 at 2:02 pm

    Mark,

    One reason why languages that truly support first class citizenship of all entities in the language (as in Lisp) is that they are very good for creating problem-specific or task-specific languages. When you look at the early AI work at MIT, for example, researchers like Winograd, Sussman, and Hewitt typically built languages on top of LISP (Planner, Conniver, … ) better suited to the tasks at hand (e.g., the Blocks World) than bare LISP would have been. If you look back at Logo (which supported full functions, recursion, etc. not carried forward into Scratch), you see people like Cynthia Solomon creating, within Logo, task-specific tools (“Teach”) to get across big ideas to small users. I have less knowledge of the history of SmallTalk but sense that a similar tension and creativity wound through it’s evolution.

    I have come to believe that this is actually the fundamental tradeoff in design of languages: how do you balance providing full power versus providing a low ceiling, and who has access to that full power, at what cost? For example, if the way to go beyond the basic language is to drop into a lower level language and write extensions, that restricts who really has access to the richness of (say) creating a special purpose language for musical composition or driving a robot (as 2 examples). Whereas, if task-specific extensions are easily written in the base language itself, then there is more room for end-user growth — but only if that extra power doesn’t scare the key audience away. Optional libraries that offer additional functionality within the basic structure of the language may be a winning strategy. Organizing themes such as functions and objects can make that easier, but first class citizenship (such as closures, the ability to pass continuations as parameters, etc) seems key in the base language, even if unused by most entry level programmers.

    Great post!
    Best, Mark

    Reply
  • 11. Jeffrey A Graham  |  March 25, 2019 at 3:07 pm

    Does VBA count as task specific? I am thinking mostly of macros in excel. If so, I don’t see it as being any easier.

    Reply
    • 12. Mark Guzdial  |  March 25, 2019 at 4:48 pm

      I don’t know VBA well. My sense is that it’s meant, like Basic, to be a general purpose language. I was blown away by how much the social studies teachers we were working with liked Vega-Lite. It’s easy and powerful. The stats in Sarah Chasin’s work are amazing. It really is possible to make Web-scraping learnable in a short time.

      Reply
      • 13. Jeffrey A Graham  |  March 25, 2019 at 7:13 pm

        I will check that out. Might be some project fodder for my stats students.

        Reply
  • 14. gasstationwithoutpumps  |  March 26, 2019 at 3:42 am

    What about task-specific languages that aren’t full programming languages, but which share a number of concepts (and syntax) with them. I’m thinking specifically of gnuplot, which is a powerful language for producing plots, but which lacks many features of a programming language and is probably not Turing-complete.

    Or there is TeX (which is Turing-complete), which can be very hard to program in, but which comes with lots of macro packages (mostly on top of LaTeX) which allow some pretty amazing stuff to be done fairly easily.

    I think that gnuplot provides a lot of transferable skills to other programming languages (at least ones in the same family as C), while TeX provides fewer transferable skills, even though TeX is the more powerful and more extensible language.

    Reply
    • 15. Mark Guzdial  |  March 26, 2019 at 11:20 am

      Terrific examples – thank you!

      Reply
  • 16. David Young  |  March 26, 2019 at 11:40 am

    UNIX seems to come with several task-specific languages: the regular expression languages, the diff/patch language, and awk.

    An unusual property of the diff/patch language is that there is a strong resemblance between the program and its inputs and outputs. To put it another way, the program largely consists of literal text in the language of the input and the output. The language of semantic patches for C (http://coccinelle.lip6.fr) also has that property. These patch languages seem to be approachable and usable in greater proportion to their power than general-purpose languages are. In this way they are appropriate for the problems they solve.

    I wonder if it is generally true that expressions in an appropriate task-specific language resemble the inputs and outputs?

    Reply
    • 17. Mark Guzdial  |  March 26, 2019 at 7:51 pm

      I agree that UNIX has a bunch of “little languages” (I heard Brian Kernighan once give a talk on them, with that title) for different purposes. They do seem to be task-specific languages, but for developer’s tasks. That matches the definition (as much as we have one). I’m more intrigued by task-specific languages for end-users.

      BTW, I know of no other task-specific language where the expressions match the input and output.

      Reply
      • 18. Raul Miller  |  March 27, 2019 at 11:20 am

        Task specific languages for end users? MIDI? WordPerfect (if you can still find it)? HTML? …

        But “task-specific language where the expressions match the input and output” … that … well, for example, if we ignore computers for a moment – music might be an example?

        Reply
  • […] domains in the school curriculum. Rather, we should explore some multi-lingual solutions, with some task-specific programming languages, and think hard about creating transfer between […]

    Reply
  • […] I’ve been thinking about more since the discussion about task-specific programming languages (see previous post here). Her essay is: What Kids Can Learn Through […]

    Reply
  • […] written several posts about task-specific programming languages over the last few weeks (here’s the first one), culminating in my new understanding of computational thinking (see that blog […]

    Reply
  • […] con seems to be more influential. I’m not saying that programming isn’t hard. There are (1) good (2) arguments for it being hard. Probably, most of my papers make and/or use that argument. What I […]

    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,638 hits
March 2019
M T W T F S S
 123
45678910
11121314151617
18192021222324
25262728293031

CS Teaching Tips