MacRuby is Apple’s open-source ruby implementation. It is implemented on top of the Cocoa framework, allowing you to run natively Ruby applications on their OS. Because of this, MacRuby applications are as fast as their Objective-C counterpart, even when it comes to threading and concurency. Being able to code in the language you like is definitely a great adventage, and having Apple develop such a framework is a great news for every Ruby programmer out there.
Starting a new MacRuby application doesn’t require a lot. Once the interpreter is installed, you are good to go. MacRuby takes adventages of Ruby 1.9 syntax, and also adds its own new syntax to support keyword arguments, which are widely used in Objective-C.
Even if MacRuby is great, Objective-C is a really well thought language. Ruby and Objective-C share a lot of similarities. They are both derived from the Smalltalk family. Message passing is at the heart of both language. Although Objective-C is a strict superset of C, its object model is dynamic and allows duck typing. This is done through the use of a generic type for object, `id`.
Like in Ruby, it’s possible to re-open a class definition through what’s called `Categories`.
Writing MacRuby code still requires opening Cocoa documentation, which is written for Objective-C. That’s why it’s still necessary to understand how to read Objective-C.
Objective-C message passing syntax is something like that:
[myObject aMessageWithOne:"Argument" andANumber: 24]
The above line sends to ‘myObject’ the ‘aMessageWithOne:(String)andANumber:(Int)’ message. As you can see, arguments are parts of the message name. That’s somehow different to Ruby. That’s why MacRuby added a new syntacting construct when adding methods, keyword arguments:
def aMessageWithOne( argument, andANumber:number )
It’s worth noting that Ruby 2.0 plans on adding keyword arguments as well.
Having tried MacRuby, I’m impressed by how well it integrates with Apple’s toolchain. It’s possible to create applications using XCode and design graphically the interface with what used to be Interface Builder (prior to XCode 4). It’s even possible to add MacRuby applications to the Appstore.
Since MacRuby is a Ruby interpreter, Ruby’s gem ecosystem are available. However, you need to ‘freeze’ them if you want to use them in a bundled .app file. Also, I wouldn’t use gems for any app-store application.
Something worth noting is that while doing MacRuby, you’ll be reading so much Objective-C code that in the end, you’ll be able to write applications using Objective-C directly. The choice for writing an app in MacRuby shouldn’t be because you don’t want to learn Objective-C, rather because you can express yourself better in Ruby.
I’m interested to see how MacRuby evolve, and I hope it gets more momentum. Objective-C is a great language but is still fairly low-level (it’s still C). Memory management and pointers, as abstract as they are, still represent low-level computer architecture. It’s only normal to shift away from this. Afterall, languages are meant for humans, and the higher level they are, the more we can focus on the core problem.
Homoiconicity leverage metaprogramming for the languages that implement it. Why?
A homoiconic language is a language that treats code as a first-class citizen. Code is merely data expressed in a primitive data structure of the language that is manipulable like any other data-structure.
There’s no distinction between code and data, they both use the same data structure. Code can then be passed anywhere and manipulated by functions to return a different code. The resulting code can the be evaluated if necessary, or stored somewhere for later use.
In order to be homoiconic, a language needs to unify data and code under a common data structure. LISP chose lists. LISP’s lists can be used as a data representation format, or as code. Io, due to its object-oriented nature, chose ‘messages’ as the unifying structure.
But a language doesn’t need to be homoiconic to allow metaprogramming.
One of the draw-back I find in homoiconic language is also one of its strength. The code looks more like an abstract syntax tree than a technical report, or a book (like we like it so much when we use literate programing.)
I did this, for fun:
It’s a program that looks like a camera. It transformes your JPEGs into polaroids with a caption. Like that:
Emacs is such a wonderful piece of technology. I saw Richard Stallman a few month ago and although his talk was very interesting, I just couldn’t think about anything else than “wow, he’s the guy who invented Emacs”. But anyway, I digress.
Emacs’ strenght is its extensibility. Adding functionality to it is really easy and fun. As a support for my markdown-literate-programming-for-github-pre-processor, I decided to add a function that can be triggered in the “markdown-mode” major mode that simply adds a fenced-code block, like that, after the point (the cursor):
In order to do that, here are the steps that I needed to take:
The `md-fenced-code-blocks` is a really easy function to create. All I needed to do was adding characters, and moving the point at the center of the code block.
(defun md-fenced-code-blocks () "Adds a fenced block for code in markdown" (interactive) (insert "~~~~ruby\n\n~~~~") (previous-line))
This can be added in the scratch buffer, however, I have all my defuns in a separate file. Next thing I had to do was defining the key-binding when markdown-mode is selected.
Emacs modes have multiple hooks that are called when an event is triggered. Selecting markdown-mode triggers all the functions defined in the `markdown-mode-hooks` variable. Using the `add-macro` function, it’s easy to add a hook function to a list of hooks.
(add-hook 'markdown-mode-hook '(lambda () (local-set-key [M-return] 'md-fenced-code-blocks)))
Et voilà! I can now press M-return and have the `md-fenced-code-blocks` function called whenever I’m in the markdown-mode.
Yesterday, I wrote about literate programing. But why should we care about it? What is code anyway?
As mighty as it might sound, code isn’t much. By itself, code is merely some characters typed in a text file. IDEs might make it look special, with all the syntax highlighting and the auto-completions, but it’s just plain old data.
Without the proper tools, source code wouldn’t even create programs. It’s because we have interpreters or compilers that our source code makes sense. It’s these tools that create a program out of code. Yet is it necessary to know how these tools operate in order to know how to code? Of course not. Why?
Because programing languages are formal. There can’t be any ambiguity when we express ideas with them (most of the time at least.)
Writing a source file in a programing language isn’t telling the machine how to do something at the low-level (which register has to be used, etc.) but what to do using the abstraction provided by the language.
In other words, writing code is writing specification for the software. Code tells the system what to do, not how to do it. For this reason, code doesn’t limit itself to machines, but can be used to communicate with anything that understands it.
While writing code, you don’t need to care if it’s going to be compiled or interpreted. This is something your tools will impose. The only thing you can do is telling which instruction, in which order, you want the system to execute.
So why are these things important? Because the main audience for code isn’t machines. It’s us. To machines, code isn’t even executable, they need to analyze it and transform it into something completely different before it can either be compiled or interpreted. It’s important to keep in mind that we are writing for other people, not for computers.
As a developer using Github, we often find ourselves browsing other people’s code. Sometimes it’s out of curiosity, sometimes it’s because we need to make a maintenance task, but in either case, it’s something valuable because peer review is a fantastic way to gain experience.
I think the code browsing experience could be even greater if the code was written directly for humans, if it was “literate”. It would allow the code:
Github has a fantastic Markdown rendering engine that is applied on each markdown files. Markdown allows you to define titles, links, code blocks, and so much more. It is a perfect candidate for writing literate programming code. It is also much more easy to grasp than LaTex for beginners.
By writing code in Markdown, using the code blocks syntax, it is possible to leverage literate programming on Github.
Of course, Markdown files can’t be executed, but by having a tool that extracts only the code part of the markdown file, and nothing more, we have a valid source file ready to be executed.
I created this tool, you can find it here: https://github.com/mikaa123/lilp
Here is an example project written in markdown: https://github.com/mikaa123/lilplateform
Would you consider source-files written in Markdown to be more readable? What are your thoughts on it? I’m curious to hear what you think (@_ms123)