6

The only place I have really noticed this sort of programming style is with the graphics engines. Essentially like this:

graphics.clear()
graphics.setStrokeStyle(myStrokeWidth)
graphics.beginStroke(myStrokeColor)
graphics.beginFill(myFillColor)
for (i = 0; i < myPoints.length; i++) {
  graphics.lineTo(myPoints[i][0], myPoints[i][1])
}
graphics.closePath()
graphics.endStroke()
graphics.endFill()

You start the process with beginFill, and then do some drawing, and then end with endFill. That is, a single piece of functionality (filling the graphics) is done over multiple method calls rather than just one:

graphics.fill(...)

I don't really know of another place that does it like this, which is why I'm wondering where this paradigm comes from. Wondering if it is for performance reasons, or for some other reason. Also would be interested where else this pops up, but not necessary for the question.

The question is why it's done this way. I would instead just implement it as graphics.fill(...). Under the hood (with the multi-step begin/end paradigm, (oh another sort of similar is with LaTeX or HTML begin/end tags, but not quite the same)), you would have to set a locally global variable (e.g. current graphics context) which would be being modified. It's like doing:

var currentFill
graphics.beginFill = function(){
  currentFill = { lineTos: [] }
}
graphics.lineTo = function(point) {
  currentFill.lineTos.push(point)
}
graphics.endFill = function() {
  graphics.draw(currentFill)
  currentFill = null
}

Another way of doing it would be passing it in (this seems like how you would do it nowadays):

graphics.beginFill = function(){
  return {}
}
graphics.lineTo = function(fill, point){
  fill.lineTos.push(point)
}
graphics.endFill = function(fill){
  draw(fill)
}

So wondering if there is some sort of history to this, or if it's an optimization thing or something else. It seems like an anti-pattern because there is hidden state, but not sure.

  • 1
    By "fill" do you mean to fill the interior of a polygon with a solid color? – 1201ProgramAlarm Aug 19 '18 at 4:22
  • 3
    I guess you are overthinking this. There are old, similar concepts like block structure/scope in programming languages, or transactions, but I doubt there is a "single historic source" for this API design - if you want to be sure, you need to ask the API's authors. Moreover, a "graphics context" object can typically have a lot of state variables like current color, current font, current line thickness and so on, which all change the behaviour of the next drawing commands, and I don't see a "fill mode" to be very different from those. – Doc Brown Aug 19 '18 at 7:51
  • People did things differently when they were writing C for a 386 – whatsisname Dec 22 '18 at 14:45
  • I guess I'm old fashioned...I would simply classify this as idiomatic procedural coding with minimal or no encapsulation. – Dave Nay Dec 22 '18 at 16:11
1

The "paradigm" behind this (if one likes to call it that way) is simply the idea of using brackets as a form of grouping. Wikipedia dates the historic roots of this concept back to 1608.

Specificially for the described use case, I would guess the idea is to avoid having tons of lineTo commands which need to be passed all the same fill parameter over and over again, which would make the code more "noisy". So yes, it is an "optimization", but not regarding performance, but readability.

Note Python's turtle package seems to have a similar fill syntax. It was inspired by Logo's turtle graphics, but the original fill syntax in Logo was a little bit different.

0

I don’t know how much further back it goes, but that is very similar to the original Mac QuickDraw API. OpenRgn and CloseRgn.

Basically it’s just a variation on what nowadays gets called the builder pattern.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.