fmt.Printf("%s", func() string {
if condition {
return "yes"
}
return "no"
}())
(or a map[bool]string and mymap[condition])
Also some relatively recent discussion on this list.
> Short answer: no.
I had the impression from the abovementioned discussion that
a properly thought through proposal would not be rejected out
of hand. (And part of my interpretation of that is that it should
include some analysis of what it would achieve if used in the
Go codebase.)
Chris
--
Chris "allusive" Dollin
package main
import "fmt"
func main() {
QC := func(c bool, a, b interface{}) interface{} {
if c {
return a
}
return b
}
fmt.Printf("the answer is %s\n", QC(true, "red", "no! blue..."));
fmt.Printf("the answer is %d\n", QC(false, 24, 42))
}
-Skip
On Tue, May 17, 2011 at 12:09 PM, Travis Reeder <tre...@gmail.com> wrote:
Note that this won't short-circuit, i.e. QC(true, "no problems!",
panic("oh no!")) would panic, but the hypothetical ternary op. would
not.
--
Arlen Cuss
Software Engineer
Phone: +61 3 9877 9921
Email: ar...@noblesamurai.com
Noble Samurai Pty Ltd
Level 1, 234 Whitehorse Rd
Nunawading, Victoria, 3131, Australia
Yes. And it is because of this subtlety that Go doesn't have this kind
of syntax. Too much logic packed into a small space makes for
unreadable programs.
Andrew
> QC := func(c bool, a, b interface{}) interface{} {Note that this won't short-circuit, i.e. QC(true, "no problems!",
> if c {
> return a
> }
> return b
> }
>
> fmt.Printf("the answer is %s\n", QC(true, "red", "no! blue..."));
> fmt.Printf("the answer is %d\n", QC(false, 24, 42))
> }
panic("oh no!")) would panic, but the hypothetical ternary op. would
not.
-Skip
CoffeeScript supports the x?a:b syntax but
it doesn't mean what you think it means.
x?y means if x then x else y, and a:b is an
object literal with a single field a with value b.
So x?a:b means if x then x else a:b.
Russ
main()
{
int i, j, k;
i = 0; j = 1;
k = i ? i++, j : j++, i;
printf("%d %d %d\n", i, j, k);
i = 0; j = 1;
k = i ? (i++, j) : (j++, i);
printf("%d %d %d\n", i, j, k);
}
-Skip
Well, even if Go acquired conditional expressions you
couldn't write what you had above, so whether or not
you miss it doesn't seem to be relevant.
It's an interesting mix of comma-expressions, conditional
expressions, and increment expressions, but it's value
as evidence against the value of conditional expressions
is diminished -- I'm tempted to say, destroyed -- by it's
not having a purpose beyond exhibiting the peculiarities
of C's expression syntax.
Chris
(Yes, I did already know that conditional expressions
are more tightly binding than the comma-operator.)
--
Chris "Oscar Wilde" Dollin
-Skip
Java has no comma-operator, and that hasn't stopped its conditional
expression being useful. C code can use conditional expressions without
needing the comma operator to make them "useful".
What a hasty grep through the Jena sources (because they're to hand and
written by several people with different styles) suggests is that there are
two common cases and two less-common ones.
The common cases are "return Ex ? Ey : Ez" and "Type V = Ex ? Ey : Ez".
Usually the Ei are all pretty simple. Sometimes there are cascaded
conditions
return T1 ? V1
: T2 ? V2
: T3 ? V3
: V
The less common cases are assignments and arguments to function calls.
Actually I'm not sure I can see a conditional argument in this samply.
Again the Ei are not particularly complicated.
So this suggests to me that the comma operator is a red herring, and
that the mere possiblility of having horribly complicated conditional
expressions does'nt mean that conditional expressions need be horrible,
no more than plain arithmetic expressions with array subscripts and
function calls need be horrible.
That argument would also exclude && and ||.
> Too much logic packed into a small space makes for
> unreadable programs.
Maybe, but that doesn't tell us how much is "too much". All I can
say is that I've not found conditional expressions to cause
unreadability /of themselves/, and I've encountered uses of
ifs, loops, and breaks that were unreadable with no conditional
expressions in sight.
For some definition of "real".
> (let ((a -3)
> (b 2))
> (display (cond ((> a b) "greater")
> ((> (abs a) (abs b)) "modulus greater")
> (else "not greater")))
> (newline))
>
> The ternary operator in C is only a hack by placing the "if"
> expression over all other expressions.
I don't understand what you mean by "placing the "if"
expression over all other expressions."
> But what makes the "if"
> expression more important than all other expressions?
I don't know. Was anyone relying on "if" expressions being
more important than others?
Conditional expressions are distinguished from infix expressions
by (amongst other things) having three operands, not two,
just as prefix expressions are distinguished by having only one.
The number of operands is not an "importance" of an expression.
> So the Go way of life "either all or nothing" is consequent. Although
> I also would have preferred all to nothing. ;-)
"All" is a bigger universe than even I am prepared for ...
No, because the if /statement/ -- in common with most of C's
statements -- doesn't have a value. ?: /is/ the if-expression.
(unlike, say, Algol 68 or Bliss.)
> Instead of writing:
>
> print_string ( if (a) { "true" } else { "false" } );
>
> The C fathers invented:
>
> print_string (a ? "true" : "false");
Probably following on from C's ancestor BCPL, which used
`Etest => Etrue, EFalse`.
> And this raises the question: why has a the "if" expression a special
> form and the "while" expression or any other not?
Because for the other forms there isn't a clear rule determining
what the result value would be [1], nor was there significant pressure
for giving while/break/continue/goto/switch/for value-returning
forms.
[1] I mean that there isn't a natural and obvious way (for C) to
decide among the possible rules for these structures, not that
no such rules can be constructed.
Other languages may have natural and obvious rules arising
from their choices of syntax and semantics.
--
Chris "allusive" Dollin
Two things: (a) it doesn't work usefully for break, continue, goto, or
switch, especially the latter; (b) as I said, I mean that there's no
clear rule /for choosing the rule to use/. There are lots of clear rules
you could apply, and you've picked on, but on what grounds?
(c) What's the value of a for/while which doesn't iterate?
Chris
--
Chris "nobody expects the spangled intromission" Dollin
> A good rule of the thumb could be "What is most practical?". And this
> discussion shows: an "if" that returns a value is practical for many
> people.
As I said earlier about why `if` was privileged over `while` etc
nor was there significant pressure
for giving while/break/continue/goto/switch/for value-returning
forms.
It's about practicality (and usefulness), not completeness.
>> (c) What's the value of a for/while which doesn't iterate?
>
> To do something when it is useful does not make it necessary to do the
> same when it is not useful.
That may be true. Are you claiming that it is not useful to define the
value returned by a for loop that doesn't iterate, or that it's not useful
to define the value of a for loop at all?
Chris
(who has in his hands a language which defines the result value(s)
of a for loop, whether or not it it iterates zero times.)
--
Chris "allusive" Dollin
The point is that people very often come up with horrible unreadable
logic using it, and for some reason they find that ok. It's much more
difficult to come up with a horrible unreadable 'if' version of the
same logic without it being obvious that it's horrible and unredable.
--
Gustavo Niemeyer
http://niemeyer.net
http://niemeyer.net/blog
http://niemeyer.net/twitter
BLUFF.
> and for some reason they find that ok. It's much more
> difficult to come up with a horrible unreadable 'if' version of the
> same logic without it being obvious that it's horrible and unredable.
Well, that's what culture-building and code reviews are for.
http://groups.google.com/group/golang-nuts/browse_thread/thread/206a3e00e28c589c#9b886de560dbdb40
In Scala, a for loop evaluates to a list of the values that are
yielded by each iteration. Thus, a loop that doesn't iterate evaluates
to an empty list. I don't, however, think this behaviour would be
useful for Go because it hides the allocation from the programmer.
I think the ternary operator is unique in that it is concise and
consolidates the assignment, clarifying intent. A loop doesn't have
the duplication of an if-else. A switch is likely going to be large
enough to warrant a function if need be.
Simply good formatting (hello gofmt) can deal with a lot of the more
ungainly looking ones, and restraint with the rest.
Well, firstly I discussed those examples in that very thread,
and secondly, it doesn't support "... people very often".
I can paste in a page of straightfoward examples as
counteranecdotes if you like.
No, thanks. The fact you can do wonderful things with Uranium is not
an argument to stock it in your backyard.
</bikeshed>
Fortunately conditional expressions aren't Uranium [1] and nobody
is attempting to stock their programs with it to the exclusion of
all other statements, not to mention good taste.
The existence of a plentiful supply of allegedly-non-horrible
conditional expressions is intended to bring a sense of relief
to those who have been over-exposed to the horrible variants.
Chris
--
Chris "[1] Jeremy .. bring Uranium" Dollin
Your examples for "bad" use of conditional expressions are more often
than not just poorly formatted (we have gofmt) or just plain silly.
Hardly Uranium.
I would like to see this page of allegedly-non-horrible conditional
expressions :).
> I would like to see this page of allegedly-non-horrible conditional
> expressions :).
I'll attach it so it's not in-your-face for the uninterested, and prune
the To: & Cc: lists down just to golang-nuts.
So I did this on the Jena [RDF toolkit, Java, yada yada] core checkout:
find -name "*.java" | xargs grep "\?" | grep " : " | grep -v "<?" |
grep -v Test | sed -e 's/[^:]*:[ \t]*//' > qq.text
\? to find conditional expressions or a part thereof, " : " to try and get
the else-part as well, "<?" to strip out some funny generics (probably
unnecessary), and sed to strip out the leading filename & whitespace.
Then I trimmed it down to the first 100 (out of 995 matching lines),
because 100 lines is a big page but 995 lines is a three-volume novel.
We lose the multi-line examples -- I know they're there, I wrote
some of them -- but I think this is illustrative enough.
(Interestingly, highlighting the conditionals like this has shown
me some duplication that might want a bit of attention ...)
All for loops in OCaml evaluate to unit:
# let a = for i = 0 to 10 do 42 done;;
Warning S: this expression should have type unit.
val a : unit = ()
(as should the expressions within)
--
Arlen Cuss
Software Engineer
Phone: +61 3 9877 9921
Email: ar...@noblesamurai.com
Noble Samurai Pty Ltd
Level 1, 234 Whitehorse Rd
Nunawading, Victoria, 3131, Australia
+1
The argument that syntax makes for horrible and unreadable code is a complete red herring as I've seen ugly unreadable code in every language I've ever worked in, including Lisp - and the latter is hardly over-burdened with syntactic complexity.
Two of my favourite languages - Ruby and Icon - are expression-oriented and support the x ? a : b syntax. In both cases I use it routinely in place of if-then-else for short expressions where the resulting code would be easier to read. Icon being goal-directed goes a step further and allows me to use the ternary operator to catch expression failure, much like we use recover in Go to catch panics :)
Arguably as Go is statement-oriented this syntax isn't as good a fit for the language, but like a number of others I'd still quite like to have it available at times where conciseness improves readability.
Ellie
Eleanor McHugh
Games With Brains
http://feyeleanor.tel
----
if _, ok := reality.(Reasonable); !ok { panic(reality) }