Wednesday, May 2, 2012

Transcribe with textmate

Transcribing with TextMate is surprisingly easy. All it takes is a new bundle with two commands, one that takes you back by three seconds, and one that pauses or plays.
#!/usr/bin/env osascript
tell application "iTunes"
     set currTime to get player position
 
     if currTime < 3 then
         set currSkip to 0
     else
         set currSkip to currTime - 3
     end if
 
    set player position to currSkip
end tell

And here is play pause:

#!/usr/bin/env osascript
tell application "iTunes" 
     playpause
end tell

Tuesday, December 13, 2011

TextMate 2.0 alpha is out

Things that did NOT make it into the alpha:
  • Split views: Yes, I actually had this on the alpha milestone, I’m not overly excited about this feature myself, but I know it’s a very common request, so eventually it should find its way into the application.
  • Full screen mode: This is mainly because we are hesitant to go Lion-only so we are holding back with “lionizing” TextMate till we feel confident we can fully drop backwards compatibility.
  • Performance: Overall performance is fine, but there are still edge-cases that we haven’t looked into, for example the long lines issue which also exists in 1.x or opening files that exhaust TextMate’s memory space.
  • Bundle editor: While a proof-of-concept bundle editor is included, it is provisional, has some flaws, and not how we envision the final bundle editor to be.
  • Settings: Not everything in the Preferences window has an effect at the moment and several menu settings are not sticky, some even revert when switching tabs. Those can be set via .tm_properties — more about this in an upcoming post.

Update: I, for one, can't actually start it. It crashes upon load.

Sunday, December 11, 2011

Lack of excitement for Pharo 1.4 seems symptomatic

Here's Lukas Renggli, the working horse that pulls Smalltalk behind him, announcing his plans for Pharo 1.4, or his lack thereof:
Just to repeat myself: With Pharo 1.4 having uncountable changes in core parts of the system and with the system including more and more forked and increasingly incompatible versions of packages (AST, RB, FS, Shout, Regex, …) I am unwilling to go through the same pain as with Pharo 1.3 again. In the current state, I don't see any of the code I am involved with (including Seaside, Magritte, Pier, OB, PetitParser, …) to move forward. I suspect that moving to another development platform soon causes less pain than to move to adopt the next Pharo :-(
In a word, nobody wants to upgrade to new versions of Pharo. But that was the whole point of Pharo: progress, moving ahead. There isn't a Smalltalk with traction right now. You can watch the Smalltalk community fail to answer which part of the Smalltalk universe is worth looking at at Stackoverflow.
Compare this with the spirit in the Objective-C/Cocoa world:
It’s OK to support only the newest version of iOS.
Now, you might say that this isn't a fair comparison, because writing iOS apps is the key to a new and exciting and fast-growing market, the mobile platform. But I think that's the same argument that Eric Schmidt is getting wrong about Android: “Whether you like Android or not, you will support that platform”. As Gruber points out, he's having cause and effect backwards: developers love programming for iOS, and only therefore is iOS as exciting as it is.
Smalltalk simply isn't as inviting to developers as it used to be.

Monday, December 5, 2011

I'm thru with the GPL

Free software is great. Seeing your own project being used and maintained by somebody else is great, too. But being expunged from the version history is a really bitter thing to experience. I'm moving my projects to Apache License, which requires attribution.

Tuesday, August 30, 2011

Point-free programming in Smalltalk

Smalltalk does not, ordinarily, support point-free programming. Point-free programming is programming without "points", or variables. In a loop, rather than assigning every item to loop over to a variable, you only write which function should be called on them.

Pharo Smalltalk has limited support for that. There, you can write:


#(1 2 3 4) select: #even -> #(2 4)


The above is implemented using an easy equivalence. Every block that sends only one message is equivalent to the selector of that message. Thus, the above is equivalent to:


#(1 2 3 4) select: [:e | e even] -> #(2 4)


Which is just standard Smalltalk. The equivalence can be made work by implementing #value: etc. on Symbol.

Well, of course this is rather limited, we still haven't got rid of blocks. We still need blocks for everything that does not only send one message. You can push a little farther by allowing composition of symbols:



{'100' . '20' . '3'} sort: #<= * #first. -> #('100' '20' '3')


The idea is to read the asterisk as "after", like the function compositor in Mathematics.

So you read this as "sort the area by less than, after first was applied". Thus, the strings are sorted by their first letter. Awesome, eh?

This is not standard Pharo, but it can be implemented in a couple of minutes. The code is on Snipt, but it's more easily written than read.

This can still not replace blocks. For example, the following block still cannot be expressed point-free:

[:a | Transcript show: a]
.

But nothing is easier than inventing a syntax for that (can you implement it in Pharo, so it'll work?):

 Transcript delayedSend: #show: 


Finally, for blocks where the left-hand-side is the argument:

 [:stream | stream nextPutAll: 'hello']


I propose that could be written as follows (can you implement it in Pharo, so it'll work?):

Delayed nextPutAll: 'hello'


Open questions


Would it be more enjoyable to write entirely point-free in Smalltalk? What do you think?

Monday, January 24, 2011

How to obtain the current time in a number of standard APIs:

I googled for the programming language plus "current time", and obtained the following methods. The programming languages are the most popular languages on github.

Ruby:

now = Time.new

Java:

Date now = Calendar.getInstance().getTime();

Python:

now = datetime.datetime.now()

C#:

DateTime now = DateTime.Now;

PHP:

now = time()

Objective C:

now = [NSDate date]

JavaScript:

var now = new Date();

C++ (well, this is really C):

time_t now = time(NULL);

These are the standard methods in the standard APIs. Nonetheless, they introduce “Hidden global state” into your application (see Slide 16 on “Clean Code Talks - Global State and Singletons” in the Google testing blog). Hidden global state makes your code hard to test, yet it is ubiquitous. Somebody should do something about that! (Yes, I’m working on it :)

Wednesday, October 27, 2010

Full text search in Pharo?

Pharo does have something like full text search across all methods, and it works like this: Rightclick the text you'd like to search for, and choose "extended search" from the options. Then, choose "method source with it." A progress bar will appear, and you should get your answer within a minute. That has to do with the source not being loaded into Pharo at all times, it is read on demand out of the sources file.

However, the compiled sources are in memory from the start. While you can't meaningfully search compiled sources, you can search the string literals within. Again, rightclick the text you'd like to search for, and choose "extended search" from the options. But now, choose "method strings with it." That will bring up a list of all methods that contain the selected text as a string literal—instantly.