# CocoaBasic concepts compared to Objective-C

CocoaBasic is a new development with some goals in mind. These goals gave strongly influenced many of the solutions described here:

- keep as close as possible to the BASIC dialect if REALbasic by REAL software, Inc.
- allow to use all features of Objective-C (incl. dynamic class and selector lookup)
- allow to access all classes and objects of the Cocoa Framework provided by Apple
- allow to access classes stored in Plugins

## Variables and Objects

Description forthcoming.

## Method calls

In Objective-C, a typical method call looks like
o=[a objectForKey:@"my key"];
The braces are used to denote a message to be sent to the object a (most probably an instance of NSDictionary). The method itself is called objectForKey: and has a single argument, in this case a constant string. The result of this call is stored in the variable o.
In CocoaBasic, the same statement would be formulated as
o=a.objectForKey("my key")
We note the differences: the braces are replaced by the . operator and the argument is enclosed in round parenthesis.
Finally, there is no semicolon to close the line. Obvoius, isn't it?
So, what about a method with more than one argument? Let's take another example for NSMutableDictionary
[a setObject:o forKey:@"my key"];
What is different? The result is ignored, and there is a second keyword forKey: before the second argument.
How does this look in CocoaBasic?
a.setObject(o, forKey:"my key")
Ok, this is just a statement and not an assignment to a variable. The first part setObject(o is as expected from the first example. But then comes the second argument. As a tribute to Objective-C, the forKey: part must also be specified in CocoaBasic.
And as a final example, lets retrieve the number of entries in the NSDictionary.
i=[a count];
In CocoaBasic we now have several options:

i=a.count | that is straightforward
i=ubound(a) | aha, ubound() is a builtin function that translates to the count method
i=ubound a | the parentheses are not necessary in this case

Now, the general rules:

- a builtin function is translated into a method call (supplying all required keywords)
- a method can be called explicitly by using the . operator
- if the method has no arguments, none are specified in CocoaBasic (omitting the parenthesis)
- a single argument is specified in parenthesis
- if more than one argument is to be supplied, they are comma-separated in the parenthesis and starting with the second, the additional keywords of the method are supplied
- The parenthesis can be omitted. In that case, the argument evaluation does not cover arithmetic operators. I.e. ubound a+5 adds 5 to the result of ubound(a) instead of taking a+5 as the argument.

And, there is an exception to every rule:

- there may be a keyword to the first argument as well. This is simply appended to the method name, i.e. a.set(Object:a, forKey:"my key") is the same as the example above.
- And the keywords may be omitted. In that case, they are replaced by withType: where Type is a string derived from the data type of the argument passed at that position (except for the first argument, where nothing is replaced). This may be withDouble:, withInt:, withObject:, etc.

So, finally some examples and their translation:

CocoaBasic Method Call | Translation to Objective-C
--- | ---
a.count | [a count]
ubound(a) ubound a | [a count]
a.objectForKey("key") a.objectForKey "key" | [a objectForKey:@"key"]
a.setObject(o, forKey:"key") a.setObject o, forKey:"key" a.set(Object:o, forKey:"key") a.set Object:o, forKey:"key" a.(setObject:o, forKey:"key") ???? | [a setObject:o forKey:@"key"]

## Methods with variable argument lists

There are methods like [NSString stringWithFormat:@"format %@", arg] which take a variable number of arguments.
They are currently not handled properly by CocoaBasic and CocoaScript.
For these functions, keywords for the additional variable arguments are ignored. I.e.

CocoaBasic Method Call | Translation to Objective-C
--- | ---
NSString.stringWithFormat("fmt") | [NSString stringWithFormat:@"fmt"]
NSString.stringWithFormat("fmt %@", x) | [NSString stringWithFormat:@"fmt %@", x]
NSString.stringWithFormat("fmt %@", value:x) | [NSString stringWithFormat:@"fmt %@", x]

## Calling instance and class methods

Instance methods are called by applying the . operator to an instance. Example:
o=new NSWindow
o.makeKeyAndOrderFront(nil)
msgbox o.title
In this case, o is initialized with a fresh instance and then the method title is called.
Compare this with
i=NSWindow.defaultDepthLimit
which calls a class method without creating a new instance. In fact, NSWindow evaluates to the class which can be accessed like an instance.

## Controlling the data type of method arguments

Method arguments are automatically translated to some extent to what Cocoa asks for. This is done by evaluating the method signatures. Here some rules

Method expects | CocoaBasic | Translation
--- | --- | ---
BOOL | pass expression resulting in Boolean | translated to BOOL (integer)
int | pass expression resulting in Integer |
long | pass expression resulting in Integer |
float | pass expression resulting in Single or Double |
double | pass expression resulting in Single or Double |
NSPoint | pass Array [x, y] - x, y are Single or Double | two elements are translated to NSPoint
NSRange | pass Array [location, length] | two elements are translated to NSRange
NSSize | pass Array [width, height] | two elements are translated to NSSize
NSRect | pass nested Array [[x, y], [width, height] | four elements are translated to NSRect
id or object of specific class | pass object | no translation

## CocoaBasic Operators and precedence

CocoaBasic understand the following operators (with precedence). Operators of the same level are evaluated from left to right. Operators of a lover level have a lower range, i.e. a*b+c*d is the same as (a*b)+(c*d).

Level | Operations | Description
--- | --- | ---
1 | object | basic object like variable, string or numeric constant, class constant
| function(...) | builtin-function call
| -a not a len(a) | operator call
| new type(...) | create new instance
| (a) | change precedence, i.e. evaluate a first
| [a, b, ...] [] | form array
| [ka:a, kb:b, ...] [:] | form dictionary
2 | object.method(arg, ...) object.method arg, ... | method call
| array(index, ...) | get value of array (from object, function result, operator etc.)
3 | a^b | exponential
4 | a*b a/b a mod b a div b a\b | multiply and divide
5 | a+b a-b | addition and subtraction
6 | a>b a>=b a<b a<=b a=b a<>b a isa class | value comparisons check for class membership
7 | a and b | logical and
8 | a or b a xor b | logical or

## Functions and Subroutines

description forthcoming.

## Builtin constants, variables and functional commands

description forthcoming.
Include builtin functional commands (niladic functions):

Symbol | Operation/Translation
--- | ---
app | access the NSApp object
nil | the nil object
self | the object for which the method is evaluated
super | the superclass (object)
false | evaluates to the Boolean false value
true | evaluates to the Boolean true value
beep | not yet implemented
quit | not yet implemented
userCancelled | not yet implemented

## Builtin functions

Builtin functions are translated into method calls (for convenience). Here is a list (not that the parenthesis may be omitted in many cases):

Function | Translation into method call
--- | ---
-x | x.CSchs
bitwiseand(a, b) | a.CSbitwiseAnd(b)
bitwisenot(a) | a.CSbitwiseNot
bitwiseor(a, b) | a.CSbitwiseOr(b)
bitwisexor(a, b) | a.CSbitwiseXor(b)
left(s, n) | s.left(n)
len(s) | s.length
lowercase(s) | s.lowercaseString
mid(s, p) | s.mid(p)
mid(s, p, n) | s.mid(p, length:n)
msgbox(s) | s.msgbox
not x | s.CSnot
right(s, n) | s.right(n)
showurl(s) | s.showurl
ubound(a) | a.count
uppercase(s) | s.uppercaseString
str(a) | [NSString stringWithFormat:@"%g", a]
val(a) | s.doubleValue

## Data types and Classes

description forthcoming.

## Some special notes

### A note about alloc, retain, release, autorelease

These methods are heavily used when programming in Objective-C - and are a source of many headaches. CocoaBasic automatically tracks and hides their use, so that you should never need them in your CocoaBasic programs. Nevertheless, you can issue them - at your own risk.

### A note about init, dealloc

The init method can be hidden in the new operator of CocoaBasic. The rule is that newcalls the alloc method and then issues an init method where you can specify additional arguments in parenthesis as usual:

o=new NSWindow | o=[[NSWindow alloc] init]
o=new NSObject(5) | o=[[NSObject alloc] init:5]
o=new NSWindow(WithWindowRef:12345) | o=[[NSWindow alloc] initWithWindowRef:12345]
o=new NSDictionary(WithContentsOfFile:"file/path") | o=[[NSDictionary alloc] initWithContentsOfFile:@"file/path"

Simply, new x translates to x.alloc.init.

### A note about copy, mutableCopy

Description forthcoming.

### Constants

description forthcoming.

### Case sensitivity

You may be used to Basic dialects where upper and lower case charaters make a distinction only within string constants but neither in keywords, variable names, or constant names. CocoaBasic has a set of special rules to allow to address all Cocoa classes and features.

Area | case sensitive (i.e. a is not the same as A) | case insensitive (i.e. a and A are the same)
--- | --- | ---
keywords (e.g. FOR, NEXT, IF, THEN, AS, END) |  | x
variable names (e.g. a, b, C) | x |
constant names (e.g. NSStringEncoding) | x |
method names (initWithData) | x |
array names (e.g. d(5), E(1,2,3)) | x |
builtin-function names (e.g. left(x)) |  | x
builtin type names (e.g. double, string) |  | x
operators (not x, new x) |  | x
builtin constants/variables (self, app, super, true, false) |  | x
string constants ("This is a Constant") | x |
class name constants (e.g. NSString) | x |
exponent of floating point numbers (e.g. 1e9) |  | x

Last change: 21 Mar 2003 - ©hns@dsitri.de, 2003