20 ms·
Anyone else love Smalltalk's message syntax. Objective-C uses it too. It has got to be the best syntax invented for a programming language. To see what I mean c
by cconroy 13y ago
Anyone else love Smalltalk's message syntax. Objective-C uses it too. It has got to be the best syntax invented for a programming language. To see what I mean compare the normal procedural code vs. the OO version:
(a)
drawRect(50, 50, 10, 21)
(b)
aRect drawAtX: 50
andY: 50
width: 10
height: 21
- JoeAltmaier 13y agoI guess that's better in a COBOLly sort of way. I'd prefer a tool that let me investigate the signature and validate the arguments if I was interested; otherwise its awfully wordy and slow to write/read.
- programminggeek 13y agowordy maybe, but incredibly easy to understand upon coming back to the code. At least, more than a list of 5+ unnamed arguments in an arbitrary order made up by someone you'll never meet and you can only understand by looking at the api docs, if there are any.
- JoeAltmaier 13y agoI'd agree, except arguments are rarely just a list of numbers. With well-named constants, methods and variables its pretty clear what's being passed.
- programminggeek 13y agoYes, but in the case of a sometimes inconsistent API, you get things like string methods that are sometimes method(needle, haystack) and sometimes method(haystack, needle) and so on. If you were sending properly labeled messages, like you are forced to do in just about every web api ever, you can at least inspect the message to get an idea what is going on. It's sort of weird to me that so much effort goes into making programming languages expressive, yet we cling to incredibly terse method names, sometimes too terse, and no labels on method inputs. So, if you don't know what some bit of code does, you have to figure out what the methods are doing and what arguments they are supposed to take. I guess to me it's like if you had to do a dictionary lookup for every word you read and had minimal context to understand a words meaning in the context of the other words around it. At the very least you would cling to a dictionary if you wanted to get anything done.
- noblethrasher 13y agoUndoubtedly slow(er) to write, but I think "slow to read", as in comprehend, needs some evidence.
- protomyth 13y agoHave you actually programmed in COBOL? I find it nothing like COBOL. Maybe AppleScript, but not COBOL. I find it faster to read since I don't have to glance at API docs at the same time.
- chc 13y agoIt's nice sometimes, but other times it gets in the way and makes lines so noisy that you end up needing to split that function call into eight lines just to be able to read it tomorrow.
- masklinn 13y agoNote that Obj-C's APIs tend to be much more verbose than Smalltalk's generally were. Compare Objective-C's enumerateObjectsUsingBlock: aBlock to Smalltalk's do: aBlock or NSDictionary's objectForKey: aKey to Smalltalk's at: aKey
- chc 13y agoThat's true. I suppose what I was thinking of is more an artifact of Objective-C's quirky typing than a problem with Smalltalk's message syntax.
- masklinn 13y agoThere's that, Objective-C's options or errors returning doesn't help, NextStep/Apple seems to be very much in long message names, and some patterns/conventions of Objective-C also factor into it (e.g. `[NSArray arrayWithArray: anArray]`, smalltalk would just say `anArray copy`)
- chc 13y agoTrue, though [anArray copy] is idiomatic in Objective-C too. It used to be that people would prefer arrayWithArray: because copy returns an owning reference and you'd need a matching release, but now with ARC that isn't really a going concern. I'd feel weird writing [NSArray arrayWithArray:anArray] these days. I think the majority of Objective-C's verbose conventions are artifacts of the Frankenstein type system — for example, having two methods with the same selector but different signatures will cause any use of either method with an id type to emit warnings, and possibly to generate incorrect code if the types are not compatible. So in order to avoid these awkward situations, Objective-C prefers to be as explicit as possible about what it's getting and giving. (Case in point: The extra verbosity in the examples you gave is almost entirely caused by adding nouns.)
- noblethrasher 13y agoC# isn't too terribly worse: aRect.Draw(x:50, y:50, width:10, height:21);
- protomyth 13y agoI look at those commas and wonder why? Is there a reason other than "must keep separators from normal function call"?
- taternuts 13y agoit kind of helps me visually dissect the parameters better - I'm sure if I got used to omitted commas it wouldn't be that big of a deal. When I would run into ruby code that omitted the parenthesis on a function call, it was considerably tougher to read for me.
- noblethrasher 13y agoLabeled parameters are optional. In fact they're so optional, that you don't even have to label all of the parameters at a call site (just the ones that appear after the first labeled parameter). So with that (mis)feature, eliding commas would make a lot of code harder to reader.
- masklinn 13y ago> So with that (mis)feature, eliding commas would make a lot of code harder to reader. Not really. Lisps get by without them and it doesn't have formal keyword parameters.
- noblethrasher 13y agoTrue, but that's an advantage of Lisp's uniformity. Imagine passing a query comprehension (or two) as arguments. Foo(from n in range select n * n into: from n in range where n % 2 == 0 select n)
- cema 13y ago
- protomyth 13y agoI still like it best, but also like the combo the current Objective-C allows. Mainly, it makes it easier to remember what the heck each parameter is supposed to be while reading the code. Its nice to have that information in the code instead of looking at the docs.
- joe_the_user 13y agoIt sounds neat. I've wanted this kind of thing when I programmed in languages that didn't have it. But having gone from c++ to Ruby to C++, I think the benefits of this expressiveness may not really be there. This construction makes each line of the whole program that much longer, it asks that every functions arguments be meaningful outside the context of the function as well as within. Basically, this syntax may show you that certain calls are wrong but there are many other calls it won't prevent and it gives you larger amount of code to page through to find those other errors. Remember, a good program wouldn't be using 10 as a function input except if there was some reason it's meaning was clear. And a rect would take two points rather than four ambiguous ints. So what you can have is drawRect(Pt(screenLeft, screenTop), Pt(screenRight, screenBottom) if you want a rect covering the screen and you want expressiveness.
- benjComan 13y agoIn Smalltalk you define points with '@' so you could do... drawRectOrigin: 50@50 extent: 10@21. drawRectOrigin: 50@50 corner: 60@71. If you really wanted, on class Point you could define method ',' with parameter 'otherPoint' as follows... , otherPoint ^ Rectangle origin: self corner: otherPoint. then you could do draw rectangles like this... drawRect: (50@50),(60@71). drawRect: (screenLeft@screenTop),(screenRight@screenBottom).
- renox 13y agoThis looks nice on toy examples, but you aren't supposed to litter your code with numerical constants.. With variables, the readability difference is much lower, it helps avoiding mistake, but IMHO it would be better to use types to detect those mistakes..