29

in JavaScript:

function getTopCustomersOfTheYear(howManyCustomers, whichYear) {
   // Some code here.
}
getTopCustomersOfTheYear(50, 2010);

in C#:

public List<Customer> GetTopCustomersOfTheYear(int howManyCustomers, 
 int whichYear)
{
   // Some code here
}
List<Customer> customers = GetTopCustomersOfTheYear(50, 2010);

in PHP:

public function getTopCustomersOfTheYear($howManyCustomers, $whichYear)
{
   // Some code here
}
$customers = getTopCustomersOfTheYear(50, 2010);

Is there any language out there which support this syntax:

function GetTop(x)CustomersOfTheYear(y)
{
    // Some code here
}
returnValue = GetTop(50)CustomersOfTheYear(2010);

Isn't it more semantic, more readable form of writing a function?

Update: The reason I'm asking this question is that, I'm writing an article about a new syntax for a new language. However, I thought that having such syntax for declaring methods could be nicer and more friendly to developers and would decrease learning-curve of the language, because of being more closer to natural language. I just wanted to know if this feature has already been contemplated upon or not.

10
  • 13
    It might be easier to read, once you get used to the idiom, but it seems to me it would be difficult to write a correct parser for that. Aug 22, 2011 at 17:35
  • 2
    What do you mean by "placeholders?" This question is hard to understand as posed, though the last code example is reminiscent of Objective-C and SmallTalk.
    – greyfade
    Aug 22, 2011 at 17:44
  • 3
    AFAIK Smalltalk was the first language using this syntax exclusively like 'hello world' indexOf: $o startingAt: 6 or Rectangle width: 100 height: 200. Btw., what's wrong with this question?
    – maaartinus
    Aug 22, 2011 at 18:20
  • 8
    If you move a parenthesis, you get: returnValue = GetTop(50, CustomersOfTheYear(2010)) which looks to me equally readable, and actually more flexible/orthogonal. ...and yeah, it's plain normal syntax.
    – dagnelies
    Aug 23, 2011 at 21:16
  • 2
    @arnaud: I totally agree. The proposed syntax is only a workaround for lacking decomposition.
    – back2dos
    Nov 19, 2011 at 21:30

16 Answers 16

40

Yes, and yes. Yes there's such a language, and yes, many people find it more readable once they get used to it.

In Objective-C, the method would be:

- (NSArray*)getTop:(int)count customersOfTheYear:(Year)year;

That's actually a pretty contrived example that doesn't read very well, so here's a better one from actual code:

+ (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;

That the prototype for a method that returns a new UIColor instance using the red, green, blue, and alpha values. You'd call it like this:

UIColor *violet = [UIColor colorWithRed:0.8 green:0.0 blue:0.7 alpha:1.0];

Read more about message names with interspersed parameters in The Objective-C Programming Language.

7
  • 16
    First time I read about it in Objective C I thought it was clever, but it's actually named parameters made more stiff and harder to manage. Apart from that, good answer.
    – ZJR
    Aug 24, 2011 at 15:28
  • 2
    An example of how the method is invoked would not go amiss.
    – greyfade
    Aug 24, 2011 at 16:58
  • 3
    @ZJR, despite Wikipedia's opinion to the contrary, Obj-C's style is like named parameters, but different. In the example above, the method name is: +colorWithRed:blue:green:alpha:. I happened to use names for the parameters that match the method, but I could as easily have used r, b, g, and a. With named parameters such as JavaScript offers, you'd use the actual names given to access the values. True names parameters can also usually be given in any order, and parameters may be optional. So similar, yes, but fundamentally different.
    – Caleb
    Aug 24, 2011 at 21:42
  • 2
    I was thinking python: color(r=0xFF,g=0xFF,b=0x55) or color(b=0x32,r=0x7F,a=.5,g=0xFF) and so on. Let's call those very named parameters, then. :)
    – ZJR
    Aug 25, 2011 at 0:14
  • 3
    @ZJR, your python example is right on -- that's exactly what I'd call "named parameters." I'm just saying that Obj-C really doesn't give you that at all. The syntax looks a lot like JavaScript's named parameters because the method is broken up into parts, and each part has a colon, but it's really not that at all. The names in Obj-C are part of the method name, not names that can be used to refer to the parameters in the implementation; order matters; parameters aren't optional. I suspect we probably agree more than not.
    – Caleb
    Aug 25, 2011 at 4:33
26

Answer: smalltalk

http://en.wikipedia.org/wiki/Smalltalk

'hello world' indexOf: $o startingAt: 6 is like Java's "hello world".indexOfStartingAt(o, 6)

Rectangle width: 100 height: 200 is like Java's new Rectangle(100, 200)

The syntax is... expression word1: parm1 word2: parm2 word3: parm3 ... The name of the method called is the concatenation of all the words.

17

I believe you are looking for the abstraction called "fluent interface (I am hereby raising a comment, originally made by @Jesper, to an "answer")." This now common pattern has been successfully implemented in many languages, of which Objective-C is only one.

Here is a pretty clean example:

Person bo = new Person();
bo.Set.FirstName("Bo").LastName("Peep").Age(16).Size("Little").LostHerSheep();

You can see how something like this can be implemented in Randy Patterson's How to design a fluent interface.

Andre Vianna gives a brief history and then discusses possible implementations in two more article parts, including plenty of useful information. Vianna points back to the old idea I first encountered in Smalltalk 80 called "cascading," that enabled sending multiple messages to the same object. It looked like this:

aThing one: 'one';
  two: 'two';
  other.

Cascading subsequently evolved into "method chaining," where we "Make modifier methods return the host object, so that multiple modifiers can be invoked in a single expression." Method chaining later grew up to become the fluent interface concept we know and use frequently today. What you plan to do looks very similar.

Ayende Rahien discusses how "fluent interface" may differ significantly enough from "method chaining" to deserve its own name.

Fluent interfaces are commonly seen in some of the new tools used in behavior driven development (BDD) and have even found their way into NUnit, a major .NET unit testing tool, in its new Constraint-Based Assert Model.

These basic approaches have subsequently been implemented in other languages, including Ruby, Python, C#, Objective-C and Java. To implement something similar, you will want to study up on the idea of "closure," which is pretty much fundamental to chaining and fluency.

Perhaps you can improve on these models; that's how we get great new languages. Still, I believe that fully understanding method chaining and fluent interfaces will give you a great starting point from which to evolve your ideas!

4
  • 2
    +1 for most researched answer so far, though adding examples and re-wording for readability might help.
    – haylem
    Aug 24, 2011 at 2:34
  • @haylem, thank you for making me go back and add examples and a bit more detail! Aug 24, 2011 at 16:30
  • 3
    Upvoted because it's a good description of the fluent style, but please note that this really isn't what the OP is asking about. As I read it, the question relates to interspersing parameters with parts of the name of a single function or method. Note the proposed function declaration: function GetTop(x)CustomersOfTheYear(y). This is a single function, not chained calls to two different functions.
    – Caleb
    Sep 20, 2011 at 20:02
  • @Caleb I think here he's trying to point out that these infix parameters are an inflexible way to do either a fluent interface (this answer) or named parameters (another answer). So far I haven't seen any advantage to them that a fluent interface/named parameters can't do better.
    – Izkata
    Feb 13, 2014 at 4:00
15

Objective-C does that. Here is a typical prototype:

- (void) areaWithHeight: (float) height andWidth: (float) width;

Here is how you call such a method:

float area = [self areaWithHeight: 75 andWidth: 20];

Objective-C is primarily used with Cocoa for Mac OS X and Cocoa Touch for iOS, but gcc will build Objective-C code on just about every platform that gcc works on.

1
  • Sorry that bullet should have been a hyphen. I guess hyphens in answer text are taken as markup. Hyphens in Objective-C are used to declare methods that belong to an object - [foo bar: x] where foo is an object or class instance - while plus signs are used for class methods, what C++ refers to as static member functions. Aug 22, 2011 at 17:47
13

In Common lisp, you can define keyword arguments for a function like this:

(defun area (&key width height)
    (* width height))

The function is called like this:

(area :width 2 :height 3)

In Ada you don't need a special declaration - you can call any procedure or function alternatively by listing the arguments in order, or by naming the arguments like this:

a := area(width => 2, height => 3);

Finally, the boost library includes a layer of hacks to add the feature to C++: http://www.boost.org/doc/libs/release/libs/parameter/doc/html/index.html

5

I couldn't find the name of it, but there's a design pattern to accomplish something similar, where a function call returns a new object modified as described. For example:

query = db.getTopCustomers(50).forYear(2010);

It isn't used very often because your data has to be very orthogonal in order to avoid unmanageable complexity under the hood, but can be useful in the right circumstances.

3
  • 6
    This is called the fluent interface design style.
    – Jesper
    Aug 22, 2011 at 21:52
  • @Jesper, what I see is very similar to jQuery chaining. Am I right? Aug 23, 2011 at 4:45
  • Yes, @Saeed, jQuery uses this style. Aug 23, 2011 at 13:38
5

Python has keyword parameters. Function definition example

def getTopCustomers(count,year):
...

Function call example

x = getTopCustomers(year=1990, count=50)

(I understand this is not be quite in the spirit of the original question, but if keyword parameters in lisp qualifies, so do this. In Smalltalk and Objective-C, however, the keywords between arguments are really part of the function name/lookup.)

1
  • I personally like this better, for this gives you the option to call the function without the parameter names if you know the order of the parameters Oct 6, 2013 at 2:38
4

Agda has mixfix notation

if_then_else x y z = case x of
                     True -> y
                     False -> z

 if cond then x else y

Whenever the function is named with an underscore, it can be split into two parts with an argument in between

4

While not a programming language per se, Cucumber takes parameters in the middle of function names, which can include spaces and are meant to look like English.

The 'functions' are defined in Ruby however

# definition
Given /^I calculate (.*) times (.*)$/ do |x, y|
    @result = x.to_i * y.to_i
end

Then /^the result should be (.*)$/ do |v|
    @result.should == v.to_i
end

# usage
Scenario:
    Given I calculate 6 times 9
    Then the result should be 42
4

In TeX you can define macros having an “argument pattern” which basically means that your calling protocol is free. For your specific example, you could use

\def\getTopCustomers#1OfTheYear#2;{%
  The #1 top customers of the year #2.
}
\getTopCustomers 50 OfTheYear 2010;

Note that it is also possible to get rid of the ; if you agree to play with registers:

\newcount\customers
\newcount\year
\def\getTopCustomers#1OfTheYear{%
  \customers#1\relax
  \afterassignment\reallyGetTopCustomersOfTheYear
  \year
}
\def\reallyGetTopCustomersOfTheYear{%
  The {\the\customers} top customers of the year {\the\year}.
}
\getTopCustomers 50 OfTheYear 2010

TeX allows you to reconfigure its lexer, and thanks to the \afterassignment macro I used above, you can use built-in procedures to lex numbers. It is very useful to define very terse calling protocols. For instance, it is very plausible to write TeX macros understanding Markdown notation for tables.

Now you ask “how do I access my database where customers are stored from TeX?” but this is another question. :)

In Common lisp, this is definitely possible to define a query macro allowing you to write

(query getTopCustomers 50 OfTheYear 2010)

where getCustomers and OfTheYear are interpreted as symbols. It is then the job of the macro to make sense of it. Common lisp is excellent in the domain of code readability (yes, I mean it!) because the macro system allows to easily create pseudo-languages tuned for your application. (I think they are called application languages.)

P.S.: It seems that nobody quoted C++. The closest you can get (without the preprocessor) is

query.getTopCustomers(50).OfTheYear(2010):

the trick is to let getTopCustomers returns a reference on query (or anything else) that also implements OfTheYear. You can build this example up to a small query language but then you have to identify final properties (returning a value) or add a finalise method (performing the lookup and returning the value). If you feel like it, you can also imitate stream controllers of the STL and be able to write things like

query << getTopCustomers(50) << OfTheYear(2010) << flush;

but this is again going in the direction of application languages.

Edit: I overlooked @han answers, that also quote Common Lisp and C++ (but not TeX!).

2

In JavaScript or any other language that supports closures, you can curry a function like this:

function getTopCustomersFunc(count) {
    return function(year) {
       // run some query, return count customers from year
    }
}
var top20Func = getTopCustomersFunc(20);
var top20Customers2005 = top20Func(2005);
var top20Customers2008 = top20Func(2008);
1
  • 1
    +1 because this is interesting, but remember that the '20' in top20Func is no longer a parameter but part of the name that reminds you of the parameter. You could just as easily say: var top5Func = getTopCustomersFunc(37);. The '5' is misleading here, but the code works exactly the same as if the variable had been named top37Func.
    – Caleb
    Sep 20, 2011 at 20:08
1

This depends on your definition of "language", but the robotframework testing framework lets you define keywords this way. From their documentation on embedded arguments:

Select ${animal} from list | Open page | pet selection
                            | Select item from list | animal_list | ${amimal}

The above declares a new keyword (essentially a function) named "select ${animal} from list" where '${animal}' is a parameter. You call it like "select cat from list"

1
  • This seems to me like SQL statements. +1 Aug 25, 2011 at 4:52
1

Inform 7.

To create (employee - a person) being paid (salary - a number):
    say "Welcome to your new job, [name of employee]!";
    choose a blank row from the table of employees;
    now the paid entry is the salary;
    now the name entry is the name of the employee.

And so on.

2
  • 3
    This doesn't exactly explain how syntax of the language works. Many people are not familiar with the Inform language and cannot distinguish the parameters from the call or its use in other areas of the code.
    – user40980
    Feb 16, 2013 at 22:33
  • I am kind of intrigued by this language. Answer was rather short with only an un-elaborated code sample, but so were the samples given by the OP (although with more conventional languages). Wiki has a nice article to read about it.
    – YoYo
    Mar 11, 2016 at 4:47
0

Common Lisp's keywords have already been mentioned, but Common Lisp's macros also allow this fairly easily:

(defmacro get-my-element (from list at index)
  `(nth ,index ,list))

This can then be called like so:

(get-my-element from '(a b c) at 1) ;returns B

One thing to note, though, is that the terms from and at are not enforced. There has to be something there, skipping them entirely is an error, but since the macro just ends up discarding them, it doesn't matter much what they are beyond readability (which is important):

(get-my-element from '(a b c) 3 1) ;also returns B
-2

In Clojure, it is common to use keyword arguments for situations like this, e.g.:

(get-customers :top 50 :year 2010)

Keyword arguments are fairly flexible, they can be optional and have defaults specified etc.

-4

You can emulate this in python. For example,

def GetTop(customers, ofYear):
  #write some code here to get the customers

print GetTop(customers=50 ofYear=2010)

or even

def GetTop(**args):
  #write some code here using the same parameter names as above

print GetTop({customers: 50, ofYear: 2010})
2
  • 1
    The syntax in your second example is wrong. Also, somebody already posted this. Oct 5, 2013 at 22:02
  • this merely repeats point made (and much better explained) in this prior answer that was posted 3 years earlier
    – gnat
    Mar 11, 2016 at 6:51

Not the answer you're looking for? Browse other questions tagged or ask your own question.