Tuesday, December 20, 2011

A New Mathematica Programming Style, Part Two



The list of abbreviated operators from which this table was generated is in the previous post (Part One). Now we continue the slides from my 2007 presentation of a new Mathematica dialect.








Suggestions for Wolfram Research
  • Use the Precedence table in documentation instead of Operator Input Forms table
  • Add mouseover Tooltips with Precedence to all abbreviated operators so we can readily see their Precedence
  • Map Tones on to all abbreviated operators' Tooltips, scaled appropriately, so we can mouseover them and hear their Precedence
  • And liberate Tones from CellularAutomata; Tones should permeate Mathematica—Mathematica should sound like R2D2
Questions for Wolfram Research
  • How does PrecedenceForm work?
  • How do the "structural elements," all having Precedence = 670, work?
  • Why not make Comma right-associative with actual Precedence 670 so we can write multiple-argument Prefix functions like this:
f@a,b,c := g@i,j,k

Next: Syntax Problems 3, 4, 5 and 6

Nested matchfix violates various programming good practices

"The guiding principle [of the order of statements of code] is the Principle of Proximity: Keep related actions together."

Manipulate[
 GraphicsRow[{Graphics[Disk[]], Graphics[Disk[]], Graphics[Disk[]]},
  Spacings -> Scaled[i], Frame -> True, Dividers -> All],  {i, .1, 1}]

"If you draw a box around each statement, they should not overlap."

"As a general principle, make the program read from top to bottom rather than jumping around. Experts agree that top-to-bottom order contributes most to readability."

"The Fundamental Theorem of Formatting is that good visual layout shows the logical structure of the program."
-Steve McConnell, Code Complete

'The price paid for functional style programs without excess auxiliary variables is "a large number of brackets."'
  -Michael Trott

Postfix "afterthought" functions can't take arguments, which stymies extended command-line programming

For example, how do you enter options for Plot:

3 Cos[x] + 2 Cos[2 x] + Cos[3 x] //Plot[ ??]

Initiates to functional programming need to learn to think "inside out" or right-to-left

Procedural programmers are often less than thrilled with functional syntax

We would like to write code to emphasize what's important and downplay what's not

Illustration of Matchfix Readability Problems

Compare three versions of a simple function using increasing numbers of optional arguments

Note the violation of the Principle of Proximity

Do boxes drawn around statements overlap?

In example #3, note the code is structured to emphasize whichever expression we wish, in this case, GraphicsRow, not Manipulate, which is just the "wrapper"

Manipulate[GraphicsRow[{Graphics[Disk[]], Graphics[Disk[]], Graphics[Disk[]]},
  Spacings -> Scaled[i], Frame -> True, Dividers -> All],  {i, .1, 1}]

Manipulate[ GraphicsRow[{Graphics[Disk[]], Graphics[Disk[]], Graphics[Disk[]]},
  Spacings -> Scaled[i], Frame -> True, Dividers -> All,
  Alignment -> {Center, Center} , AlignmentPoint -> Center,
  AspectRatio -> Automatic, Axes -> False, AxesLabel -> None,
  AxesOrigin -> Automatic, AxesStyle -> {}, Background -> None,
  BaselinePosition -> Automatic, BaseStyle -> {},
  ColorOutput -> Automatic, ContentSelectable -> Automatic,
  DisplayFunction :> $DisplayFunction, Dividers -> None,
  Epilog -> {}],  {i, .1, 1}]

GraphicsRow[{Graphics@Disk[], Graphics@Disk[], Graphics@Disk[]},
 Spacings -> Scaled@i, Frame -> True, Dividers -> All,
 Alignment -> {Center, Center} , AlignmentPoint -> Center,
 AspectRatio -> Automatic, Axes -> False, AxesLabel -> None,
 AxesOrigin -> Automatic, AxesStyle -> {}, Background -> None,
 BaselinePosition -> Automatic, BaseStyle -> {},
 ColorOutput -> Automatic, ContentSelectable -> Automatic,
 DisplayFunction :> $DisplayFunction, Dividers -> None, Epilog -> {}]
// Manipulate[#,  {i, .1, 1}] &

And the more nested the function, the worse it is


Postfix/Pure Function Style: Functional-Procedural Fusion

A Solution: extended usage of Postfix and pure Function

As an alternative to this 'traditional' usage of matchfix (the error is deliberate):

expr7 [ expr6 [ expr5 [expr4 [expr3 [expr2 [expr1 ] ] ] ] ] ] ]

Consider writing this, using Postfix and pure Function:

expr1 // expr2 # & // expr3 # & // expr4 # & // expr5 # & // expr6 # & // expr7 # &

And you can write it down the page, too:

expr1 //
expr2 # & //
expr3 # & //
expr4 # & //
expr5 # & //
expr6 # & //
expr7 # &

It works as simply as this:

expr1 // expr2 #& is parsed as: expr2[expr1]

Amounts to a fusion of procedural and functional styles

Functional programming that looks procedural

FP Fusion Examples

Command line or one-liner

Sin@x//Plot[#,{x, -5, 5}]&


Extended one-liner or function

This fits the general pattern of a class of functions. You generate some data or intialize a function, then perform a few transformations on it, and then you want to view it.

Here we write it as a readable one-liner, sequentially across the page.

Clear@g; g@x_ := RandomReal[];
Table[g@i, {i, 100}] //Take[#, 80]& //100 #& //#^2& //ListPlot[#, Filling->Axis]&


Or sequentially down the page, nice and clean.

g@x_ := RandomReal[];
Table[g@i, {i, 100}] //
Take[#, 80]& //
100 #& //
#^2& //
ListPlot[#, Filling->Axis]&


If needed, we can use variable assignment within Postfix statements by appropriate parentheses:

Range@6 // (list1 = Partition[#, 3]) &; list1[[1]]

{1, 2, 3}

Summary

Computer programming's destiny is to control high-order complexity

Mathematica is a modern scientific synthesis whose core is the most advanced programming language paradigm

Mathematica's destiny is to play a lead role in the scientific challenges of our age

Version 8 shows its capabilities go far beyond those of any other programming language

Prefix and FP Fusion are a suggested improvement in syntax toward more understandable and controllable programs

Comments and suggestions are welcome: lowlevelfunctionary@kriscarlson.com

Acknowledgements and References

Stephen Wolfram

The Mathematica Book
Code examples in A New Kind of Science

Roman Maeder, harry calkins

A First Course in Mathematica
Programming in Mathematica

Roman Maeder

Programming in Mathematica 2nd Ed.
The Mathematica Programmer
The Mathematica Programmer II
Computer Science with Mathematica

David B. Wagner

Power Programming in Mathematica: The Kernel

John W. Gray

Mastering Mathematica, 2nd Ed.: Programming Methods and Applications

Michael Trott

The Mathematica Guidebook: Programming

Paul R. Wellin, Richard J. Gaylord, and Samuel N. Kamin

An Introduction to Programming with Mathematica, 3rd Ed.

Christian Jacob

Illustrating Evolutionary Computation with Mathematica

Nancy Blachman

Mathematica: A Practical Approach

Stan Wagon

Mathematica in Action

And thanks to the attendees of this talk who had valuable suggestions, in particular Paul Abbott, and their forbearance of my first effort using a Mathematica slide show





2 comments:

  1. Brilliant Post! I am an enthusiastic convert to your Fusion@Procedural//Functional style.

    ReplyDelete
  2. Hi Kieran,

    Thanks for the feedback, and for your push to post some examples of Selectors and Constructors. I learned the methodology of data structures from Roman Maeder's excellent books.

    I've been using the functional/procedural fusion for years now and it's clearly a superior dialect to Matchfix. I wonder how many keystrokes I've saved using Prefix while writing less cluttered code.

    Please let me know what else you'd like to see on the blog. I am about to become active again on it.

    I generated over a million web pages using Mathematica in the last few days. I'll be posting some notes on that soon.

    ReplyDelete