show all comments

Cairo

How Low Can You Go?

June 05, 2009 04:30:22 EDT

Recently, I had a question regarding running Cairo on VisualWorks 7.4. Is it possible?

I was curious, so I tied a bunch of balloons to my computer and set out on an adventure to find out. Here's what my journey looked like:

  1. Fire up latest version of 7.7, load NewTextFind, as something to test with.
  2. Look at prereqs, create parcels out of CairoGraphics, Pango, Weaklings, and NewTextFind.
  3. Install 7.4.1 on Vista.
  4. Copy all of the dlls for Cairo/Pango in my 7.7 image directory over to the 7.4.1 one. Copy the 4 .pcl/.pst files over
  5. Fire up 7.4.1
  6. Load Weaklings, Cairo, and Pango parcels
  7. Run a bare bones Cairo test:
    p := Pixmap extent: 100 @ 100.
    p graphicsContext newCairoContextWhile: 
    		[:cr | 
    		cr
    			source: ColorValue purple;
    			paint.
    		layout := Pango.Layout text: 'Hi'.
    		cr
    			moveTo: 20 @ 20;
    			source: ColorValue cyan.
    		layout showOn: cr].
    p asImage
  8. Discover that we added the method tag based library specification in 7.6; go look at the various win* methods on LibCairo, LibGDI, and LibPango, and put those values in the class definition libraryFiles: arrays.
  9. Rerun the test. Giggle with delight when it works.
  10. Load NewTextFind parcel.
  11. Hit ctrl-l in a text field to activate it; discover that we also added the message #half in 7.6 (Cairo doesn't use it, just NewTextFind)
  12. Add ArithmeticValue:
    half
    	^self / 2
    
  13. Chortle and Chuckle again.
  14. Go blog about it.
  15. The End

    Based on a true story. After discovering that CairoGraphics and Pango bindings for VisualWorks worked on 7.4.1 with minimal effort, Travis was last seen wandering off to bed...

Counting Belly Button Wrinkles

Arguments about Blocks

June 02, 2009 14:39:41 EDT

I was discussing with a colleague the types of keywords we surround blocks with. In particular not which message we send to them, but which types of keywords frequently get passed literal blocks as arguments. After we had asserted what we were sure was the "obvious common pattern", my interest was piqued. I sat down and wrote some code.

First I flirted with ParseTreeSearcher. This seems like an obvious thing. But it's not the right way (IMO) to do this kind of query. The ParseTreeSearcher is about matching relatively simple patterns against source trees. It uses a custom language for specifying the patterns to match.

Luckily, we're not beholden to use a ProgramNodeVistor just so we can enumerate with code that looks like someExpression ifTrue: [ noteIt ]. ProgramNode responds to nodesDo:. The query, in pseudo code, which I'm interested goes something like this:

  1. is it a block?
  2. does the block's argument count match the kinds of blocks I'm looking for (e.g. niladic, etc)?
  3. is the block an argument to a keyword message?
  4. what subpart of the selector preceded the block then?
Here's a chunk of code that sweeps my whole development image for that:
bag := Bag new.
blockArgCount := 0.
SystemUtils allBehaviorsDo: [:eachBehavior |
    eachBehavior selectorsAndMethodsDo: [:selector :ignored |
      (eachBehavior parseTreeFor: selector)
        ifNotNil: [:tree |
          tree nodesDo: [:each |
          "is it a block?"
          each isBlock
            ifTrue: ["is it the arg count I'm interested in?"
              each arguments size = blockArgCount
                ifTrue: ["is it an argument to a message?"
                  (each parent isMessage and: [each parent receiver ~~ each])
                    ifTrue: ["then record the keyword that preceded it"
                      bag
                        add: (each parent selectorParts at: (each parent arguments indexOf: each)) value]]]]]]].
top15 := ((bag contents associations
      asSortedCollection: [:a :b | a value > b value]) first: 15)
      collect: [:each | each key -> (each value asFloat / bag size)]
Here's the results for blocks of argument count 0, 1, and 2.

0 Arguments

SelectorPercent
ifTrue:46.8734
ifFalse:28.023
and:7.13361
or:4.30638
ifAbsent:2.50518
ifNil:1.08428
whileTrue:0.860953
ensure:0.825349
ifNone:0.792983
whileFalse:0.74767
ifAbsentPut:0.66999
ifNotNil:0.589073
showWhile:0.390018
should:0.351178
timesRepeat:0.309101

1 Argument

SelectorPercent
do:56.2116
collect:9.81889
select:4.85706
ifNotNil:3.74195
detect:3.52492
anySatisfy:1.81111
reject:1.55665
ifDefinedDo:1.42194
contains:0.935489
allSatisfy:0.935489
getBlock:0.898069
reverseDo:0.666068
compute:0.51639
allBehaviorsDo:0.434067
bindingsDo:0.389163

2 Arguments

SelectorPercent
keysAndValuesDo:20.0799
do:16.7832
into:9.99001
asSortedCollection:8.84116
putBlock:5.74426
put:4.74525
selectorsAndMethodsDo:3.24675
sortBlock:2.74725
onError:1.4985
block:1.34865
useTempClass:1.2987
fold:1.14885
visualBlock:1.0989
sorted:1.04895
filterBlock:0.999001

blathering philosophy

To State, or Not To State

May 30, 2009 04:03:54 EDT

I love Smalltalk. Have for a long time. Among the things I've come to love about it over the years, is as a model, which encourages binding behavior to data (state). This is a focus of problem solving in computer programming, that works well for many domains. In a universe far far away, where people don't like state, they do the functional thing and avoid it (state).

In the Smalltalk universe, we don't spend too much time thinking about stateless functions. We're usually in a search for what data, a given behavior belongs to. What is the right receiver? Whose responsibility is this? Like all simulations, this breaks down some times. There are the rare occasions where we make "utility methods". These are methods that can live anywhere. The only state they need is local state (temps and arguments). The reasons for making them are varied, but for whatever reasons, it happens sometimes. It's not always a perfect world.

Sometimes, if we get enough of these utility functions, we place them on a Class. Maybe there's a logical class that they're related to, maybe we make a new class, to act as a gathering point for these functions. One example of this, in the VisualWorks system, is the SystemUtils class. It's not the greatest example. A healthy percentage of its behavior should probably be moved to the state it truly goes with. But even after carving that all away, we end up with a chunk of utilities that have some value.

This same approach has affected, over the years, the way I do ExternalInterface subclasses. When I make one, I'm usually creating a flat facade to a reentrant (read: necessarily stateless) C library. The C functions operate on the data I pass to them. Since they're justifiably just utility methods, I treat them the same way as SystemUtils. I put the methods on the class side. Getting to that point, is a history of asking myself "why?" and getting past common idioms/patterns that we like to generally embrace.

If one doesn't follow this pattern, one has to create an instance of the utility method holder. Code like this:

     LibCairo new cairo_clip: handle.
At one point, I found myself asking "why do I do this?" Of course, there are the standard answers such as "class behavior outside of instance creation/constants is bad." But at some point, I got past that. I found myself asking "what am I gaining by creating a new instance each and every single time, other than needlessly exercising the allocator/collector and proving I like to type 'new'?" "What makes these never ending stream of new entities differ, one from another?"

Flummoxed with this situation, I began doing the "cached singleton" thing. You know the drill. Add a class instance variable called default or current. Add an accessor for it; said accessor lazy initializes the variable to the new instance. Now I'm not making an endless stream of objects, all of which differ from each other in no meaningful way, and all which just turn around and die. Now I would write code that looks like:

     LibCairo current cairo_clip: handle.

There's an amusing irony to me with this one. I now type more than I used to type ('current' vs just 'new'). And the coolest thing, is that I managed to add state to the equation. It was until then just a big bag of utility functions. But now, by creating a slot to store the singleton instance, and the code to manage it, I've managed to introduce state into the problem. It's almost like, I've done extra work, just to get state into the problem, so I can feel comfortable in my Smalltalk universe where state is so important.

This led to further application of the "why do I do this?" scalpel. Once I realize that I created an artificial/arbitrary/extra amount of state to manage, I realize that classes are objects too. And I've already got a singleton managed instance of that. Why do this caching, when I could just put the methods right there, just as well? Which brings us around to the following present day application:

     LibCairo cairo_clip: handle.
It's just a utility method. I type less this way. I write less code to intialize/access singletons this way. And I haven't figured out what I lose yet.

I just finished up converting the last ExternalInterface in CairoGraphics to follow this pattern. I removed an instance variable. Methods which set it. I was able to remove comments describing how they were managed. The code reads more direct now. This is my story of why I do ExternalInterfaces the way I do.

SuperPower Lessons?

Mutating your Process, for Instance

May 29, 2009 19:01:42 EDT

Eliot Miranda writes a great and lengthy dissertation about the value of first class contexts. This is a recurring theme in Smalltalk. It's that everything is objects, all the way down, at least to a depth not found in peer OO languages. It's not just the contexts either.

This post shows how we do instance mutants in Smalltalk, and yet another example of first class everything.

I had a hard test to write the other day. It involved two processes and potential race condition involving interruptWith: and terminate, both Process APIs. It was meant to test some code that looked, simplified, like:

	watchedProcess := Processor activeProcess.
	alarm :=  [aDuration wait. watchedProcess interruptWith: ["something happens"]] forkAt: watchedProcess priority + 1.
	["do some stuff] ensure: [alarm terminate]
The problem was that I needed/wanted to emulate reliably the rare case where watchedProcess was finished, but there was enough life left in alarm to still do the interrupt block. What I needed, for the duration of just this test, was for alarm terminate to not happen.

Smalltalk behaviors are just first class method dictionaries. Every object's class is one. These are usually ClassDescription objects, found through the normal directed graph of classes you see in your browser. But they don't need to be. Consider the following example:

| p |
p := 4 @ 3.
p negated
This produces the result of (-4 @ -3). But what if I wanted for some absurd reason to change Point behavior, not for the whole system, because likely things would come crashing down pretty fast, but just for that instance, for a bit. We could modify the code to read:
p := 4 @ 3.
p changeClassTo: (p class copy superclass: p class).
p class methodDictionary at: #negated put: (p class methodDictionary at: #transpose).
p negated
Now it returns (3@4) instead of the negated value. Just that instance. No other Point in the system will behave that way. Just the mutant one I made. What's going on? The first new line added, is how create a mutant instance. A copy is created of it's defining class, that copy is made a lightweight subclass of the original Point class we know about. We say it's lightweight because, Point doesn't know it as a subclass, so it won't show up in the system tools. And we change the instance class to be this no anonymous copy.

The third line, is then free to modify the new anonymous behavior, which it does by mucking with the methodDictionary directly, replacing the #negated method with the #transpose one.

Other than raising the hackles of the security minded, what, if anything is this good for? It can be handy for instrumenting things to discover behavior. It can be handy for temporarily "fudging" or "faking" a computation, for testing purposes, or other other code discovery. In the case of my test, it was handy for causing my alarm process behave a little differently than processes normally do, thus allowing me to reliably create what was otherwise a rare luck of the roll to get the timing right.

I was able to modify my test to read something like:

thatProcess := self codeToFindThatOneInstance.
thatProcess changeClassTo: (thatProcess class copy superclass: thatProcess class).
thatProcess class compile: 'terminate "do nothing"'.
....
Using this technique, I was able to force a process under test to take up some mutant behavior to cause the tested scenario to recur reliably. Because not only are contexts real objects, and classes first class objects, but so too are the very Processes themselves.

More Movies

Inspecting IEEE 754

May 19, 2009 03:50:15 EDT

Recently, I had a chance to play with the inspector, floating point numbers, and relearn how computers model them. I made a movie summarizing the experience, showcasing how one can explore floating point values with the Smalltalk inspector.

General

Not your Father's New Prerequisite Engine

May 05, 2009 01:18:23 EDT

A while back, I set out to integrate the NewPrerequisiteEngine add on. That work has now been integrated into the latest build of VisualWorks (7.7 may09.1). It ended up being a bit more than a "file in and include in build." The new engine is faster, but more thorough at the same time. The biggest change, is a complete rewrite of the UI. Here's a movie I put together using Screenflick and iMovie. Sorry for the poor audio transitions with my voice, I didn't give enough lead in time with the individual screencasts. And I have the sniffles because it's allergy season here.

All of the widgets (except the scrollbar) follow the development arc of using no Controller objects, and dynamic layouts supported by Panel objects. And no Wrappers.

Off Topic

Switching Safari 4 Firefox

March 08, 2009 17:07:36 EST

Generally I use Safari for most web browsing. It was/is the "native" web app on OSX after all. It feels like it "fits in" best. Occasionally, I use Firefox for a couple of web sites that don't work as well with Firefox (like writing this blog).

No more.

I tried the Safari 4 beta preview for about a week now. I hate it. So, I've made the switch.

I don't notice the speed either way. What I do notice is the screwy tab/title bar thing. I do lots of tabs in my browsing. I think the guys over at OSNews got it just about right:

This is where it goes wrong for Safari 4. There, the tabs are the titlebar, leading to a rather schizophrenic UI widget: it has to act as a titlebar and a tab bar, and consequently, does neither of the two very well. Since you have to be able to drag the window via this new tabtitlebar widget, Apple had to create a special and small handle for moving tabs, while making the tabs themselves the place to drag the window. This design decision is something I expect from a 6 year old who writes his fist tabbed text editor - not from a company that prides itself on UI design.

I've noticed this over and over again in the last week. I'll have Skype up and safari up. Safari's in the background. Someone sends me a link in my Skype chat. I click on it. The Safari window is party obscured by the Skype window, but I know that it has dutifully opened a new tab at the end with that content, in fact, I can see part of it loading. So I go to bring the Safari window forward, I don't get the click quite right on Safari window used-to-be-just-a-titlebar-thing and ta-da! instad of just raising the window, it flips to some other tab.

I found this tidbit about Safari vulnerabilities a bit disturbing as well.

SUnitToo

Resourceful Platform Specific Testing

February 28, 2009 02:15:59 EST

TestResources aren't something I've done much with. Recently, I did an update to SUnitToo TestResources to support them better. I hadn't done anything to the SUnitToo(ls) runner though, it still just raised an exception. Today, I fixed that. It handles TestResourceUnavailable exceptions much cleaner now (prints nice message, resets icon status); latest versions published in the Open/Public Repository.

I did this, because I wanted to try a simple experiment. I'm very loathe to add more thin API points on SUnitToo. When a feature comes up, I'd rather explore ways of putting the basics together, rather than fatten the API.

One such request that's been kicked around here at Cincom, is platform specific filters. We have a large suite of tests; a small subset of them really are platform specific. Sometimes people put preambles to their tests:

('*MacOSX' match: OSHandle currentPlatformID) ifFalse: [^self]
But this gets old, and you have to go look them up each time.

So I experimented with using TestResources to do this task. It turned out to be amazingly simple. Let's say I need to filter some graphics tests that are X11 specific, Windows specific, and MacOSX specific. I create three subclasses of TestResource named X11Only, MacOSXOnly, and WindowsOnly. I add one method to each.

isAvailable
	^Screen default platformName = 'X11'
isAvailable
	^Screen default platformName = 'MacOSX'
isAvailable
	^Screen default platformName = 'MS-Windows'

Now I can use these as resources for my tests that are platform specific. If they're not there, the tests will be skipped. SUnitToo actually can specify resources at the per test level, so you don't have to devolve to having special concrete test classes, inheriting off of abstract classes or anything like that. An X11 specific graphic test might look something like:

x11SpecificGraphicsText
	<test>
	<uses: #{X11Only}>

	self deny: 'blah' , blah' = 'yadayada'