Eero - Objective-C without brackets

  • Tutorial
int main()
  parts := ['hello', 'world']
  greeting := ''
  for String part in parts
    if part == parts[0]
      Locale myLocale = Locale.currentLocale
      greeting << part.capitalizedString
      greeting << ' '
      greeting << part
  Log('%@', greeting + '!')
  return 0

The other day, out of curiosity, I decided to look at what stage the Eero project is - the Objective-C dialect with alternative lightweight syntax. It turned out that a large front of work has already been done and Eero is a very interesting development.

Code example

For starters, the traditional comparison of a small piece of code on Eero and Objective-C.
@interface FileHelper : NSObject
@property (readonly) NSString* name;
@property (readonly) NSString* format;
-(NSFileHandle*) openFile: (NSString*) path;
-(NSFileHandle*) openFile: (NSString*) path
          withPermissions: (NSString*) permissions;
@implementation FileHelper
-(NSString*) name {
  return @"Macintosh";
-(NSString*) format {
  return @"HFS+";
-(NSFileHandle*) openFile: (NSString*) path {
  return [NSFileHandle fileHandleForReadingAtPath: path];
-(NSFileHandle*) openFile: (NSString*) path
          withPermissions: (NSString*) permissions {
  NSFileHandle* handle = nil;
  if ([permissions isEqualTo: @"readonly"] || [permissions isEqualTo: @"r"]) {
    handle = [NSFileHandle fileHandleForReadingAtPath: path];
  } else if ([permissions isEqualTo: @"readwrite"] || [permissions isEqualTo: @"rw"]) {
    handle = [NSFileHandle fileHandleForUpdatingAtPath: path];
  return handle;

interface FileHelper
  String name   {readonly}
  String format {readonly}
  openFile: String, [withPermissions: String], return FileHandle
implementation FileHelper
  name,   return String = 'Macintosh'
  format, return String = 'HFS+'
  openFile: String path, withPermissions: String = 'readonly', return FileHandle = nil
    if permissions == 'readonly' or permissions == 'r'
      return FileHandle.fileHandleForReadingAtPath: path
    else if permissions == 'readwrite' or permissions == 'rw'
      return FileHandle.fileHandleForUpdatingAtPath: path


Eero is a fully interface and binary compatible Objective-C dialect. Implemented using fork LLVM / clang compiler, i.e. generates binary code directly, due to which standard LLVM / Clang development tools work with it, including debugger, static analyzer and others. An experimental conversion of Eero code into standard Objective-C code 1 has also been announced .

In Eero, you can directly use all Cocoa frameworks and any Objective-C / C ++ code, you just need to connect the necessary header files. The reverse process is also easy: if the interface for an Eero-class is defined on Objective-C, then it can be used directly, binary files are fully compatible.

Essentially, Eero is a powerful syntax sugar for Objective-C, enhancing readability, security, and code. According to the author (Andy Arvanitis) , initially he just wanted to get rid of the brackets in Objective-C, and chose the name of the language when he saw a model of a pedestal table that successfully performed its functions without unnecessary interfering legs. So, the language is named after the Finnish table architect Eero Saarinen . I am not strong in Finnish, but apparently, the name should sound something like “ero” with an emphasis on the first syllable.


The documentation is written in a high-quality and easy to read manner, for each feature of the language the motivation is indicated, why they decided to do just that, basically it: readability, security, DRY , WYSIWYG . There are many interesting details in the language, I will not consider everything, but confine myself to a small subjective list.

Firstly, in Eero, indentation is used to highlight blocks instead of curly braces, as in Python. A semicolon at the end of instructions and definitions is optional.
int count = 0
while ( count < 100 )
  something = false
  i++; j++

In Eero sending messages recorded through a dot notation, for messages with no arguments is similar notation for the properties (property) . Arguments are passed after the colon, several arguments are separated by commas.
id myarray =
myarray.addObject: myobject
myarray.insertObject: myobject, atIndex: 0

Since in Objective-C you cannot represent an object in any other way than through a pointer, in Eero all class type variables are treated as pointers, without using an asterisk (*) .
NSString mystring = myobject.description
NSString otherString = (NSString) someObject

When declaring local variables, you can omit their type; it will be automatically inferred from the assigned expression. To do this, use the special operator ": =".
i := 100
mystring := myobject.description

In Eero implemented such remarkable thing as namespace (namespaces) . The prefix "NS" is connected by default, i.e. all types from the Foundation framework can be used without a prefix.
mystring := String.stringWithUTF8String: "Hello, World"

The compiler first checks the entity names as they appear in the code, and if the name is not found, adds registered prefixes. Additional prefixes are declared using the directive using prefix.
using prefix AB
theAddressBook := AddressBook.sharedAddressBook

However, in the current implementation there is a significant drawback: the occurrence of collisions as a result of omitting prefixes is not monitored in any way, just the first suitable option is used:
void AAPrint(String str)
  NSLog('AA: %@', str);
void BBPrint(String str)
  NSLog('BB: %@', str);
using prefix AA
using prefix BB
Print('test') // AA: test

In Eero, it is not necessary to specify the names of the method arguments; if omitted, they are automatically determined from the selector. For example, in the following method, the arguments will be named bytes , length, and encoding :
initWithBytes: const void*,
       length: UInteger,
     encoding: StringEncoding

The type of the return value is specified after the arguments, the default is void .
initWithBytes: const void*,
       length: UInteger,
     encoding: StringEncoding,
        return id

In Objective-C, in the case when a method has optional parameters, it is customary to define several methods with different numbers of arguments. In Eero, you can declare methods with optional parameters.
interface MyClass
  openFile String, [withPermissions: String], return FileHandle

In implementation, the default value of an optional argument is indicated by the "=" sign.
implementation MyClass
  openFile: String, withPermissions: String = 'r', return FileHandle
    handle := nil
      if permissions == 'r'
        handle = FileHandle.fileHandleForReadingAtPath: file
      else if permissions == 'w' or permissions == 'rw'
        handle = FileHandle.fileHandleForUpdatingAtPath: file
      return handle

You can specify a default return value, which, for example, allows you to define very compact getters:
implementation MyClass 
  model, return String = 'G35'
  serialNumber, return String = 'X344434AABC'

Properties are declared very simply. Attributes, if necessary, are set in braces.
interface MyClass
  String name {nonatomic, copy}
  String desc {readonly}

The indentation is used when defining blocks, and the caret sign "^" is not used. Compared to Objective-C syntax, blocks look very simple:
myblock := (int x, int y)
  if x < 0
    printf( "value was negative! (%d)\n", x )
    x = 0
  return x + y

A compact notation is also supported for simple blocks consisting only of the returned expression:
xyblock := (int x, int y | return x + y)
descriptions := mylist.mapWith: (id element | return element.description)

Eero implements operator overloading. First, for all objects, the == operator is an alias for the isEqual method . What is relevant primarily for a readable and safe string comparison:
mystring :=
mystring.appendString: 'Hello, World'
if mystring == 'Hello, World'
  // попадаем сюда, т.к. выражение выше истинно

When using the binary operator "+", the stringByAppendingString message will be sent to all objects that can respond to it (mainly NSString and its subclasses):
helloString := 'Hello'
worldString := 'World'
helloWorldString := helloString + ', ' + worldString

Similarly, the << operator sends an appendString message :
mystring := ''
mystring << 'Hello, World'

For your classes, you can overload the following operators:
+plus:Including the + = operator
-minus:Including operator - =
*multipliedBy:Including operator * =
/dividedBy:Including the operator / =
%modulo:Including operator% =
> =isGreaterThanOrEqualTo:

Well, finally, in the language at the compiler level is prohibited goto. :)

Installation and use

This section is based on experience using Eero in build 2013-12-08, XCode 5.0.2, and Mac OS X 10.8.5.

Putting Eero is very simple. Just download and install the plugin for Xcode, which already contains the assembly of the LLVM compiler fork. During installation, Xcode templates will also be added to create new .eero and .eeh files. After installation, just restart Xcode and that’s it, you can get to work.

Syntax highlighting, auto-completion works. However, the drop-down list with class navigation does not work, instead of it is the static inscription “No Selection” .

More precisely, Xcode does not see the classes and methods defined in the file, but you can use the instructions#pragma mark ..., - they are visible in the drop-down list.

Check the operation of the debugger (aka the debugger) , it's all right. However, unfortunately Xcode crashed while trying to view quick help to the highlighted code. Auto-indentation doesn’t always work correctly, but this is a trifle. No more problems found.


Personally, Eero made the most pleasant impression on me. Yes, the language is quite young (the domain was registered in January 2011, and the project appeared on the github in December of that year) , and therefore there are drawbacks characteristic of this stage of development (mainly with integration with the IDE) . However, insoluble and critical problems are not visible, and therefore I had a strong desire to try it in future projects.


1) At the moment, the conversion function Eero -> Objective-C is damp, I have successfully worked only on elementary examples.

Also popular now: