Often code is not as readable as it could be because parameters are always at the end of the function name. Ex.: addDaysToDate(5, myDate).
I thought about a more readable syntax like this:
function add(days)DaysTo(date) {
// Some implementation
}
var myDate = new Date()
add(5)DaysTo(myDate)
And you could go really crazy:
addA(5)('dollar')CouponTo(order)If(user)IsLoggedIn
So here is my question: Are there any languages that incorporate this concept?
Assuming a generous interpretation of the phrase "is there", then: Algol 60 could look like your example. Specifically, it allowed a form of comment in procedure parameters.
add(5) Days To: (myDate);
The specific rule in the grammar that permits this is:
<parameter delimiter> ::= , | ) <letter string> : (
which is to say, the parameters in a procedure statement can be separated by a comma (as is common) or by an arbitrary sequence of letters delimited by ) and :(.
Spaces are everywhere ignored, so they're ok here too.
The letter-string is treated as a comment, so as for all comments, it has no bearing on what the code actually does. This is just as valid as the previous example:
add(5) Bananas To: (myDate);
It seems curious to me now, nearly 45 years after I last used this, that the comment part can only contain letters, no digits.
<letter string> ::= <letter> | <letter string> <letter>
Revised Report on the Algorithmic Language ALGOL 60
Have a look at Pogoscript https://github.com/featurist/pogoscript
There are no keywords in PogoScript. All control structures use the same syntax rules as regular functions and methods, so it's very easy to write your own control structures
Arguments and parameters can be placed anywhere in the name of a function or method call. The careful placement of an argument or a parameter can give it a lot of meaning.
sing (n) bottlesOfBeerOnTheWall =
if (n > 0)
console.log ((n) bottlesOfBeerOnTheWall)
sing (n - 1) bottlesOfBeerOnTheWall
(n) bottlesOfBeerOnTheWall =
"#((n) bottles) of beer on the wall, #((n) bottles) of beer.\n" +
"Take one down, pass it around, #((n - 1) bottles) of beer on the wall."
(n) bottles =
if (n == 0)
"no bottles"
else if (n == 1)
"1 bottle"
else
"#(n) bottles"
sing 99 bottlesOfBeerOnTheWall
I have a sequence of length $n initialized to zeroes:
let $seq := (for $i in (1 to $n) return 0)
I can access a position easily...
return $seq[5]
...but how do I update it? (the following doesn't work)
let $seq[5] := $seq[5] + 1
If you're using an XQuery implementation which supports XQuery 3 maps (eg. Saxon, BaseX), you could use these:
declare namespace map="http://www.w3.org/2005/xpath-functions/map";
(: Fill map with square numbers :)
let $map := map:new(
for $i in (1 to 10)
return map:entry($i, $i*$i)
)
(: Overwrite a single value :)
let $map := map:new(($map, map:entry(2, 5)))
(: Fetch this value :)
return map:get($map, 2)
But generally it is possible to solve a problem without maps and in most cases this code will probably run faster as it will get better optimized.
XQuery is a functional, not a procedural language, so variables are immutable - they cannot be updated once assigned. You would need to do something like this and create a new sequence:
let $seq2 :=
for $n at $pos in $seq
if ($pos eq 5)
then $n + 1
else $n
Generally, in XQuery, it's best to design algorithms so that this type of mutable variable workaround isn't necessary. If you have data that needs to be updated, consider putting it in the database.
...but how do I update it? (the following doesn't work)
let $seq[5] := $seq[5] + 1
Using pure XPath (which is also pure XQuery :) here is probably the shortest way to specify this:
subsequence($seq, 1, 4), $seq[5] + 1, subsequence($seq, 6)
This produces a new sequence whose items are the same as the items of $seq, except that its 5th item's value is $seq[5] + 1.
As others have noted, XPath and XQuery are functional languages and among other things this means that a variable, once defined, cannot have its value modified.
I like reading about programming theories, so could you tell me if there is any object-oriented static typed language that allow variables to have a few types?
Example in pesudocode:
var value: BigInteger | Double | Nil
I think about way of calling methods on this object. If object value have type BigInteger | Double language could allow user to call only shared methods (lake plus, minus) but when the type is BigInteger | Double | Nil then object of Nil hasn't methods plus and minus, so we can't do anything usefull with this object, because it has only few shared methods (like toString).
So is there any idea how should work calling methods on variable with few types in static typed object-oriented language?
What you are describing is an intersection type. They do exist in Java, for example, but they only arise within the type-checker as the result of capture conversion and type-inference. You cannot write one yourself.
I don't know of any language which uses them directly, but they are often used to describe or analyze type systems of languages, espececially languages which don't actually have a type system. For example, Diamondback Ruby, which is a static type system and type-inferencer for the dynamically typed Ruby programming language, uses both union and intersection types.
Note that the syntax you are using is generally used to denote union types, which are the dual of intersection types. Intersection types are generally written A & B & C.
I am not aware of any language that does this... sadly, I'd love to play around with it (but first, they should adopt type inference and parametric polymorphism ;) ).
Although it is alreapossible: Relatively elegantly in a structural type system (type a is a subtype of type b if a has everything b has), simply by specifying a type for value that is a structural subtype of BigInteger and of Double and of Nil and slightly less elegantly in a nominative type system (type a is a subtype of type b if and only if it inherits from it, directly or indirectly) by specifying a common ancestor of all three (if all else fails, object). Of course we'd need to go recursive - what is the type of toString? And what's the typ of (Integer | Double | BigInteger).+?!? This is far from trivial (in fact, looking for a solution made my head hurt a bit). I can't say if it is impossible, but no mainly-OO-language's type system is anywhere sophisticated enough for a possible solution.
The bottom line is: It'd be really cool if some whizz came along and sorted out the issues it raises. Propably not worth the effort...
Edit: Do you know algebraic data types? They are similar to your idea (but much older ;) ) in that an algebraic data type is composed of several types and can therefore contain e.g. a BigInteger, a Double and Nil - the actual value is one of these and a tag (as in tagged union) says which. But to use the value stored in an algebraic data type, you have to use pattern matching to extract it safely. This concept is very powerful, and still "simple" enough to be understood tools - e.g. type inference and static typechecking work.
It has not much to do with OO but (as far as I understand it) what you describe looks much like polymorphism as implemented by C++.
Yes, OCaml has these in the form of polymorphic variants:
type my_var = Integer of int | Float of float;;
let x = Integer(10);;
let y = Float(3.14);;
Pike has them, as does Magpie, an optionally-typed language I'm working on. Google's Closure compiler for Javascript allows you to annotate types in Javascript using |.
They crop up frequently in languages that bridge static and dynamic typing because a lot of expressions in a dynamic language can yield one of a couple of types:
var a = 123;
if (foo) { a = "string"; }
bar(a);
The statically-determined type being passed to bar() is Number | String.
I'm not so sure if we really have a complete definition of what a static typed language is but I also hope that the language you describe wouldn't qualify as one.
One of my concerns is that if you add type T1 and T2 to be a part of your BigInteger | Double | Nil, how would they know about each other and how to handle the operations you defined? Now I realize you never said that the language would allow expanding the "implicit" conversion definition.
Come to think of it, C# does something that resembles this in its string handling
string s = -42 + '+' + "+" + -0.1 / -0.1 + "=" + (7 ^ 5) +
" is " + true + " and not " + AddressFamily.Unknown;
=> "1+1=2 is True and not Unknown"
string str = 1 + 2 + "!=" + 1 + 2;
=> "3!=12"
And I do not like it.
For example, I would write:
x = 2
y = x + 4
print(y)
x = 5
print(y)
And it would output:
6 (=2+4)
9 (=5+4)
Also, are there any cases where this could actually be useful?
Clarification: Yes, lambdas etc. solve this problem (they were how I arrived at this idea); I was wondering if there were specific languages where this was the default: no function or lambda keywords required or needed.
Haskell will meet you halfway, because essentially everything is a function, but variables are only bound once (meaning you cannot reassign x in the same scope).
It's easy to consider y = x + 4 a variable assignment, but when you look at y = map (+4) [1..] (which means add 4 to every number in the infinite list from 1 upwards), what is y now? Is it an infinite list, or is it a function that returns an infinite list? (Hint: it's the second one.) In this case, treating variables as functions can be extremely beneficial, if not an absolute necessity, when taking advantage of laziness.
Really, in Haskell, your definition of y is a function accepting no arguments and returning x+4, where x is also a function that takes no arguments, but returns the value 2.
In any language with first order functions, it's trivial to assign anonymous functions to variables, but for most languages you'll have to add the parentheses to indicate a function call.
Example Lua code:
x = function() return 2 end
y = function() return x() + 4 end
print(y())
x = function() return 5 end
print(y())
$ lua x.lua
6
9
Or the same thing in Python (sticking with first-order functions, but we could have just used plain integers for x):
x = lambda: 2
y = lambda: x() + 4
print(y())
x = lambda: 5
print(y())
$ python x.py
6
9
you can use func expressions in C#
Func<int, int> y = (x) => x + 5;
Console.WriteLine(y(5)); // 10
Console.WriteLine(y(3)); // 8
... or ...
int x = 0;
Func<int> y = () => x + 5;
x = 5;
Console.WriteLine(y()); // 10
x = 3;
Console.WriteLine(y()); // 8
... if you are really wanting to program in a functional style the first option would probably be best.
it looks more like the stuff you saw in math class.
you don't have to worry about external state.
Check out various functional languages like F#, Haskell, and Scala. Scala treats functions as objects that have an apply() method, and you can store them in variables and pass them around like you can any other kind of object. I don't know that you can print out the definition of a Scala function as code though.
Update: I seem to recall that at least some Lisps allow you to pretty-print a function as code (eg, Scheme's pretty-print function).
This is the way spreadsheets work.
It is also related to call by name semantics for evaluating function arguments. Algol 60 had that, but it didn't catch on, too complicated to implement.
The programming language Lucid does this, although it calls x and y "streams" rather than functions.
The program would be written:
y
where
y = x + 4
end
And then you'd input:
x(0): 2
y = 6
x(1): 5
y = 7
Of course, Lucid (like most interesting programming languages) is fairly obscure, so I'm not surprised that nobody else found it. (or looked for it)
Try checking out F# here and on Wikipedia about Functional programming languages.
I myself have not yet worked on these types of languages since I've been concentrated on OOP, but will be delving soon once F# is out.
Hope this helps!
The closest I've seen of these have been part of Technical Analysis systems in charting components. (Tradestation, metastock, etc), but mainly they focus on returning multiple sets of metadata (eg buy/sell signals) which can be then fed into other functions that accept either meta data, or financial data, or plotted directly.
My 2c:
I'd say a language as you suggest would be highly confusing to say the least. Functions are generally r-values for good reason. This code (javascript) shows how enforcing functions as r-values increases readability (and therefore maintenance) n-fold:
var x = 2;
var y = function() { return x+2; }
alert(y());
x= 5;
alert(y());
Self makes no distinction between fields and methods, both are slots and can be accessed in exactly the same way. A slot can contain a value or a function (so those two are still separate entities), but the distinction doesn't matter to the user of the slot.
In Scala, you have lazy values and call-by-name arguments in functions.
def foo(x : => Int) {
println(x)
println(x) // x is evaluated again!
}
In some way, this can have the effect you looked for.
I believe the mathematically oriented languages like Octave, R and Maxima do that. I could be wrong, but no one else has mentioned them, so I thought I would.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I'm personally an advocate of the ternary operator: () ? :
I do realize that it has its place, but I have come across many programmers that are completely against ever using it, and some that use it too often.
What are your feelings on it? What interesting code have you seen using it?
Use it for simple expressions only:
int a = (b > 10) ? c : d;
Don't chain or nest ternary operators as it hard to read and confusing:
int a = b > 10 ? c < 20 ? 50 : 80 : e == 2 ? 4 : 8;
Moreover, when using ternary operator, consider formatting the code in a way that improves readability:
int a = (b > 10) ? some_value
: another_value;
It makes debugging slightly more difficult since you can not place breakpoints on each of the sub expressions. I use it rarely.
I love them, especially in type-safe languages.
I don't see how this:
int count = (condition) ? 1 : 0;
is any harder than this:
int count;
if (condition)
{
count = 1;
}
else
{
count = 0;
}
I'd argue that ternary operators make everything less complex and more neat than the alternative.
Chained I'm fine with - nested, not so much.
I tend to use them more in C simply because they're an if statement that has value, so it cuts down on unnecessary repetition or variables:
x = (y < 100) ? "dog" :
(y < 150) ? "cat" :
(y < 300) ? "bar" : "baz";
rather than
if (y < 100) { x = "dog"; }
else if (y < 150) { x = "cat"; }
else if (y < 300) { x = "bar"; }
else { x = "baz"; }
In assignments like this, I find it's less to refactor, and clearer.
When I'm working in ruby on the other hand, I'm more likely to use if...else...end because it's an expression too.
x = if (y < 100) then "dog"
elif (y < 150) then "cat"
elif (y < 300) then "bar"
else "baz"
end
(Although, admittedly, for something this simple, I might just use the ternary operator anyway.)
The ternary ?: operator is merely a functional equivalent of the procedural if construct. So as long as you are not using nested ?: expressions, the arguments for/against the functional representation of any operation applies here. But nesting ternary operations can result in code that is downright confusing (exercise for the reader: try writing a parser that will handle nested ternary conditionals and you will appreciate their complexity).
But there are plenty of situations where conservative use of the ?: operator can result in code that is actually easier to read than otherwise. For example:
int compareTo(Object object) {
if((isLessThan(object) && reverseOrder) || (isGreaterThan(object) && !reverseOrder)) {
return 1;
if((isLessThan(object) && !reverseOrder) || (isGreaterThan(object) && reverseOrder)) {
return -1;
else
return 0;
}
Now compare that with this:
int compareTo(Object object) {
if(isLessThan(object))
return reverseOrder ? 1 : -1;
else(isGreaterThan(object))
return reverseOrder ? -1 : 1;
else
return 0;
}
As the code is more compact, there is less syntactic noise, and by using the ternary operator judiciously (that is only in relation with the reverseOrder property) the end result isn't particularly terse.
It's a question of style, really; the subconscious rules I tend to follow are:
Only evaluate 1 expression - so foo = (bar > baz) ? true : false, but NOT foo = (bar > baz && lotto && someArray.Contains(someValue)) ? true : false
If I'm using it for display logic, e.g. <%= (foo) ? "Yes" : "No" %>
Only really use it for assignment; never flow logic (so never (foo) ? FooIsTrue(foo) : FooIsALie(foo) ) Flow logic in ternary is itself a lie, ignore that last point.
I like it because it's concise and elegant for simple assignment operations.
Like so many opinion questions, the answer is inevitably: it depends
For something like:
return x ? "Yes" : "No";
I think that is much more concise (and quicker for me to parse) than:
if (x) {
return "Yes";
} else {
return "No";
}
Now if your conditional expression is complex, then the ternary operation is not a good choice. Something like:
x && y && z >= 10 && s.Length == 0 || !foo
is not a good candidate for the ternary operator.
As an aside, if you are a C programmer, GCC actually has an extension that allows you to exclude the if-true portion of the ternary, like this:
/* 'y' is a char * */
const char *x = y ? : "Not set";
Which will set x to y assuming y is not NULL. Good stuff.
In my mind, it only makes sense to use the ternary operator in cases where an expression is needed.
In other cases, it seems like the ternary operator decreases clarity.
I use the ternary operator wherever I can, unless it makes the code extremely hard to read, but then that's usually just an indication that my code could use a little refactoring.
It always puzzles me how some people think the ternary operator is a "hidden" feature or is somewhat mysterious. It's one of the first things I learnt when I start programming in C, and I don't think it decreases readability at all. It's a natural part of the language.
By the measure of cyclomatic complexity, the use of if statements or the ternary operator are equivalent. So by that measure, the answer is no, the complexity would be exactly the same as before.
By other measures such as readability, maintainability, and DRY (don't repeat yourself), either choice may prove better than the other.
I use it quite often in places where I'm constrained to work in a constructor - for example, the new .NET 3.5 LINQ to XML constructs - to define default values when an optional parameter is null.
Contrived example:
var e = new XElement("Something",
param == null ? new XElement("Value", "Default")
: new XElement("Value", param.ToString())
);
or (thanks asterite)
var e = new XElement("Something",
new XElement("Value",
param == null ? "Default"
: param.ToString()
)
);
No matter whether you use the ternary operator or not, making sure your code is readable is the important thing. Any construct can be made unreadable.
I agree with jmulder: it shouldn't be used in place of a if, but it has its place for return expression or inside an expression:
echo "Result: " + n + " meter" + (n != 1 ? "s" : "");
return a == null ? "null" : a;
The former is just an example, and better internationalisation and localisation support of plural should be used!
If you're using the ternary operator for a simple conditional assignment I think it's fine. I've seen it (ab)used to control program flow without even making an assignment, and I think that should be avoided. Use an if statement in these cases.
(Hack of the day)
#define IF(x) x ?
#define ELSE :
Then you can do if-then-else as expression:
int b = IF(condition1) res1
ELSE IF(condition2) res2
ELSE IF(conditions3) res3
ELSE res4;
I think the ternary operator should be used when needed. It is obviously a very subjective choice, but I find that a simple expression (specially as a return expression) is much clearer than a full test. Example in C/C++:
return (a>0)?a:0;
Compared to:
if(a>0) return a;
else return 0;
You also have the case where the solution is between the ternary operator and creating a function. For example in Python:
l = [ i if i > 0 else 0 for i in lst ]
The alternative is:
def cap(value):
if value > 0:
return value
return 0
l = [ cap(i) for i in lst ]
It is needed enough that in Python (as an example), such an idiom could be seen regularly:
l = [ ((i>0 and [i]) or [0])[0] for i in lst ]
this line uses properties of the logical operators in Python: they are lazy and returns the last value computed if it is equal to the final state.
I've seen such beasts like (it was actually much worse since it was isValidDate and checked month and day as well, but I couldn't be bothered trying to remember the whole thing):
isLeapYear =
((yyyy % 400) == 0)
? 1
: ((yyyy % 100) == 0)
? 0
: ((yyyy % 4) == 0)
? 1
: 0;
where, plainly, a series of if-statements would have been better (although this one's still better than the macro version I once saw).
I don't mind it for small things like:
reportedAge = (isFemale && (Age >= 21)) ? 21 + (Age - 21) / 3 : Age;
or even slightly tricky things like:
printf ("Deleted %d file%s\n", n, (n == 1) ? "" : "s");
I like using the operator in debug code to print error values so I don't have to look them up all the time. Usually I do this for debug prints that aren't going to remain once I'm done developing.
int result = do_something();
if( result != 0 )
{
debug_printf("Error while doing something, code %x (%s)\n", result,
result == 7 ? "ERROR_YES" :
result == 8 ? "ERROR_NO" :
result == 9 ? "ERROR_FILE_NOT_FOUND" :
"Unknown");
}
I almost never use the ternary operator, because whenever I do use it, it always makes me think a lot more than I have to later when I try to maintain it.
I like to avoid verbosity, but when it makes the code a lot easier to pick up, I will go for the verbosity.
Consider:
String name = firstName;
if (middleName != null) {
name += " " + middleName;
}
name += " " + lastName;
Now, that is a bit verbose, but I find it a lot more readable than:
String name = firstName + (middleName == null ? "" : " " + middleName)
+ " " + lastName;
Or:
String name = firstName;
name += (middleName == null ? "" : " " + middleName);
name += " " + lastName;
It just seems to compress too much information into too little space, without making it clear what's going on. Every time I saw the ternary operator used, I have always found an alternative that seemed much easier to read... then again, that is an extremely subjective opinion, so if you and your colleagues find ternary very readable, go for it.
I like them. I don't know why, but I feel very cool when I use the ternary expression.
I treat ternary operators a lot like GOTO. They have their place, but they are something which you should usually avoid to make the code easier to understand.
Well, the syntax for it is horrid. I find functional ifs very useful, and they often makes code more readable.
I would suggest making a macro to make it more readable, but I'm sure someone can come up with a horrible edge case (as there always is with C++).
I typically use it in things like this:
before:
if(isheader)
drawtext(x, y, WHITE, string);
else
drawtext(x, y, BLUE, string);
after:
drawtext(x, y, isheader == true ? WHITE : BLUE, string);
As others have pointed out they are nice for short simple conditions. I especially like them for defaults (kind of like the || and or usage in JavaScript and Python), e.g.
int repCount = pRepCountIn ? *pRepCountIn : defaultRepCount;
Another common use is to initialize a reference in C++. Since references have to be declared and initialized in the same statement you can't use an if statement.
SomeType& ref = pInput ? *pInput : somethingElse;
I like Groovy's special case of the ternary operator, called the Elvis operator: ?:
expr ?: default
This code evaluates to expr if it's not null, and default if it is. Technically it's not really a ternary operator, but it's definitely related to it and saves a lot of time/typing.
I recently saw a variation on ternary operators (well, sort of) that make the standard "() ? :" variant seem to be a paragon of clarity:
var Result = [CaseIfFalse, CaseIfTrue][(boolean expression)]
or, to give a more tangible example:
var Name = ['Jane', 'John'][Gender == 'm'];
Mind you, this is JavaScript, so things like that might not be possible in other languages (thankfully).
Only when:
$var = (simple > test ? simple_result_1 : simple_result_2);
KISS.
For simple if cases, I like to use it. Actually it's much easier to read/code for instance as parameters for functions or things like that. Also to avoid the new line I like to keep with all my if/else.
Nesting it would be a big no-no in my book.
So, resuming, for a single if/else I'll use the ternary operator. For other cases, a regular if/else if/else (or switch).
For simple tasks, like assigning a different value depending on a condition, they're great. I wouldn't use them when there are longer expressions depending on the condition though.
If you and your workmates understand what they do and they aren't created in massive groups I think they make the code less complex and easier to read because there is simply less code.
The only time I think ternary operators make code harder to understand is when you have more than three or foyr in one line. Most people don't remember that they are right based precedence and when you have a stack of them it makes reading the code a nightmare.
As so many answers have said, it depends. I find that if the ternary comparison is not visible in a quick scan down the code, then it should not be used.
As a side issue, I might also note that its very existence is actually a bit of an anomaly due to the fact that in C, comparison testing is a statement. In Icon, the if construct (like most of Icon) is actually an expression. So you can do things like:
x[if y > 5 then 5 else y] := "Y"
... which I find much more readable than a ternary comparison operator. :-)
There was a discussion recently about the possibility of adding the ?: operator to Icon, but several people correctly pointed out that there was absolutely no need because of the way if works.
Which means that if you could do that in C (or any of the other languages that have the ternary operator), then you wouldn't, in fact, need the ternary operator at all.