Inverted syntax: Difference between revisions
initial content |
|||
(170 intermediate revisions by 80 users not shown) | |||
Line 1: | Line 1: | ||
{{task}} |
{{task}} |
||
'''Inverted syntax with conditional expressions''' |
|||
In traditional syntax conditional expressions are usually shown before the action within a statement or code block: |
In traditional syntax conditional expressions are usually shown before the action within a statement or code block: |
||
< |
<syntaxhighlight lang="pseudocode"> IF raining=true THEN needumbrella=true </syntaxhighlight> |
||
In inverted syntax, the action is listed before the expression in the statement or code block: |
In inverted syntax, the action is listed before the conditional expression in the statement or code block: |
||
< |
<syntaxhighlight lang="pseudocode"> needumbrella=true IF raining=true </syntaxhighlight> |
||
'''Inverted syntax with assignment''' |
|||
In traditional syntax, assignments are usually expressed with the variable appearing before the expression: |
|||
<syntaxhighlight lang="pseudocode"> a = 6</syntaxhighlight> |
|||
In inverted syntax, the expression appears before the variable: |
|||
<syntaxhighlight lang="pseudocode"> 6 = a</syntaxhighlight> |
|||
'''Task''' |
|||
The task is to demonstrate support for inverted syntax forms within the language by showing both the traditional and inverted forms. |
The task is to demonstrate support for inverted syntax forms within the language by showing both the traditional and inverted forms. |
||
=={{header|6502 Assembly}}== |
|||
===Branching=== |
|||
Conditional branches are limited in the range they can branch; all branch statements cannot be more than 127 or -128 bytes away from their destination. |
|||
The below example will result in an assemble time error. The intended action is that the X variable is decremented, and execution returns to the top of the loop. However, the branch is simply too far away. |
|||
<syntaxhighlight lang="6502asm">loop_MySubroutine: |
|||
; more than 127 bytes of code |
|||
dex |
|||
bne loop_MySubroutine ;assembler will display an error message that the branch is too far away. |
|||
; rest of program</syntaxhighlight> |
|||
The easiest way to overcome this limitation is to invert the branch condition and place a <code>JMP</code> back to the loop under it. |
|||
An unconditional <code>JMP</code> moves the program counter to the specified location, no matter where that is. |
|||
<syntaxhighlight lang="6502asm">loop_mySubroutine: |
|||
; more than 127 bytes of code |
|||
dex |
|||
beq continue |
|||
JMP loop_mySubroutine |
|||
continue: |
|||
; rest of program</syntaxhighlight> |
|||
Now, what happens is that the opposite condition is checked. If X = 0, execution branches 3 bytes forward to "continue." Otherwise, the statement underneath the branch is executed, which is a jump back to the top. |
|||
===16-Bit Data=== |
|||
Being a little-endian CPU, the "low byte" (rightmost 2 digits) of a 16-bit (4-digit) hexadecimal number is stored <i>before</i> the "high byte" (leftmost 2 digits). This is difficult for a human to read but easier for the CPU. The assembler allows the programmer to use a <code>dw</code> or <code>word</code> directive to define 16-bit data values in a manner easier for a person to read. The assembler swaps the order of the bytes automatically when assembling the source code. |
|||
<syntaxhighlight lang="6502asm">word $BEEF |
|||
byte $EF,$BE</syntaxhighlight> |
|||
A hexdump of these bytes would display them the same, i.e.: <pre>EF BE EF BE</pre> |
|||
=={{header|Ada}}== |
|||
The only place where syntax is kind of inverted is <code>exit when</code> to exit loops: |
|||
<syntaxhighlight lang="ada">Foo := 1; |
|||
loop |
|||
exit when Foo = 10; |
|||
Foo := Foo + 1; |
|||
end loop;</syntaxhighlight> |
|||
=={{header|ALGOL 68}}== |
|||
{{works with|ALGOL 68G|Any - tested with release 2.8.win32}} |
|||
<syntaxhighlight lang="algol68"># Inverted assignment # |
|||
# Assignment in Algol 68 is via ":=" which is automaically provided for all modes (types) # |
|||
# However we could define e.g. "=:" as an inverted assignment operator but we would need to # |
|||
# define a separate operator for each mode, e.g. for integers and strings: # |
|||
PRIO =: = 1; |
|||
OP =: = ( INT a, REF INT b )REF INT: b := a; |
|||
OP =: = ( STRING a, REF STRING b )REF STRING: b := a; |
|||
OP =: = ( CHAR a, REF STRING b )REF STRING: b := a; |
|||
INT a, b; STRING s; |
|||
1 =: a; |
|||
a + 1 =: b; |
|||
"?" =: s; |
|||
print( ( a, b, s, newline ) ); |
|||
# There is one standard inverted assignment operator: +=: or PLUSTO which prepends a string # |
|||
# to another: # |
|||
"bc" =: s; |
|||
"b" +=: s; |
|||
print( ( s, newline ) ); |
|||
# Inverted Conditional Expressions # |
|||
# We could define an operator called WHEN perhaps, that would execute its left operand if # |
|||
# the right operand was TRUE. However the left operand would need to be a PROC VOID so the # |
|||
# syntax would not be as convientent as the standard IF-THEN-FI construct. E.g.: # |
|||
PRIO WHEN = 1; |
|||
OP WHEN = ( PROC VOID code, BOOL test )VOID: IF test THEN code FI; |
|||
( VOID: print( ( "NO", newline ) ) ) WHEN a = b; # the anonymous PROC VOID is not called # |
|||
( VOID: print( ( "yes", newline ) ) ) WHEN a /= b # the anonymous PROC VOID is called #</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
+1 +2? |
|||
bbc |
|||
yes |
|||
</pre> |
|||
=={{header|ARM Assembly}}== |
|||
Typically, instructions with a destination register and a source register will have the leftmost register be the destination and the registers to the right be the source. |
|||
<syntaxhighlight lang="arm assembly">MOV R0,R3 ;copy R3 to R0 |
|||
ADD R2,R1,R5 ;add R1 to R5 and store the result in R2.</syntaxhighlight> |
|||
However there is one exception: the <code>STR</code> command. Its source is on the left and its destination is on the right. This inverted syntax is not optional. |
|||
<syntaxhighlight lang="arm assembly">STR r0,[r4] ;store the contents of R0 into the memory location specified by R4.</syntaxhighlight> |
|||
This was most likely done for symmetry with the "push/pop" commands: |
|||
<syntaxhighlight lang="arm assembly">STMFD sp!,{r0-r12,lr} ;push r0 thru r12 and the link register |
|||
LDMFD sp!,{r0-r12,pc} ;pop r0 thru r12, and the value that was in the link register is popped into the program counter.</syntaxhighlight> |
|||
=={{header|Arturo}}== |
|||
In this case, we can define a reversed if-statement function (taking the block first, then the condition) and then "alias" a new symbol to it, as an infix operator (so that the block actually comes first, in terms of syntax: |
|||
<syntaxhighlight lang="rebol">ifStatement: function [block, condition][ |
|||
if condition -> do block |
|||
] |
|||
alias.infix {??} 'ifStatement |
|||
do [ |
|||
variable: true |
|||
[print "Variable is true!"] ?? variable |
|||
]</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Variable is true!</pre> |
|||
=={{header|Bracmat}}== |
|||
The match operator <code>:</code> can play the role of an inverted assignment operator <code>=</code>. The following two definitions of a function <code>double</code> are equivalent. |
|||
<syntaxhighlight lang="bracmat"> |
|||
double=.!arg+!arg; |
|||
(=.!arg+!arg):(=?double); { inverted assignment syntax, same result as above. } |
|||
</syntaxhighlight> |
|||
Bracmat evaluates all left hand sides of all binary operators. How right hand sides are treated depends on the operator. The <code>=</code> operator does not evaluate its right hand side at all. The right hand side of the <code>:</code> operator is evaluated by a dedicated match evaluator, which for example sees the expression <code>?double</code> as a variable to be bound to some part of the left hand side of the <code>:</code> operator. |
|||
The following two assignments are not equivalent: |
|||
<syntaxhighlight lang="bracmat">foo=3+7 { assigns 3+7 to foo } |
|||
3+7:?foo { assigns 10 to foo } |
|||
</syntaxhighlight> |
|||
=={{header|C}}== |
|||
C doesn't have a way to do this cleanly. You need to drop some code before the statements you want to invert. |
|||
I'll use CPP to make it look as close as I think you can make it. -- ksb, Jan 2013 |
|||
The original would be "if (foo()) a = 4;" Here is the inverted if logic using "otherwise ... given () ;" |
|||
<syntaxhighlight lang="c"> |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#define otherwise do { register int _o = 2; do { switch (_o) { case 1: |
|||
#define given(Mc) ;case 0: break; case 2: _o = !!(Mc); continue; } break; } while (1); } while (0) |
|||
int foo() { return 1; } |
|||
main() |
|||
{ |
|||
int a = 0; |
|||
otherwise a = 4 given (foo()); |
|||
printf("%d\n", a); |
|||
exit(0); |
|||
} |
|||
</syntaxhighlight> |
|||
Which actually makes the main program look like: |
|||
<syntaxhighlight lang="c"> |
|||
main() |
|||
{ |
|||
int a = 0; |
|||
do { |
|||
register int _o = 2; |
|||
do { |
|||
switch (_o) { |
|||
case 1: |
|||
a = 4; |
|||
case 0: |
|||
break; |
|||
case 2: |
|||
_o = !!(foo()); |
|||
continue; |
|||
} break; |
|||
} while (1); |
|||
} while (0); |
|||
printf("%d\n", a); |
|||
exit(0); |
|||
} |
|||
</syntaxhighlight> |
|||
To make lint happy you need a /*FALLTHROUGH*/ before the case 0 (in the macro). |
|||
=={{header|C++}}== |
|||
Though rarely, if ever, used in practice, user-defined class types can have inverted syntax with assignment. |
|||
<syntaxhighlight lang="cpp">class invertedAssign { |
|||
int data; |
|||
public: |
|||
invertedAssign(int data):data(data){} |
|||
int getData(){return data;} |
|||
void operator=(invertedAssign& other) const { |
|||
other.data = this->data; |
|||
} |
|||
}; |
|||
#include <iostream> |
|||
int main(){ |
|||
invertedAssign a = 0; |
|||
invertedAssign b = 42; |
|||
std::cout << a.getData() << ' ' << b.getData() << '\n'; |
|||
b = a; |
|||
std::cout << a.getData() << ' ' << b.getData() << '\n'; |
|||
}</syntaxhighlight> |
|||
It doesn't work if the left operand is not of the type <tt>invertedAssign</tt>. |
|||
=={{header|Clojure}}== |
|||
The "thread last" macro permits inversion of syntax in virtually all contexts. Any form for which the construction of a new list from consecutive elements doesn't change the semantics may be turned "inside-out"; this is to the exclusion of those containing function definitions and little else. |
|||
<syntaxhighlight lang="clojure">; normal |
|||
(if (= 1 1) |
|||
(print "Math works.")) |
|||
; inverted |
|||
(->> (print "Math still works.") |
|||
(if (= 1 1))) |
|||
; a la Haskell |
|||
(->> (print a " is " b) |
|||
(let [a 'homoiconicity |
|||
b 'awesome]))</syntaxhighlight> |
|||
Expanding the macro reveals the nature of the aforementioned limitation. |
|||
<syntaxhighlight lang="clojure">((fn [x] (* x x) 5) ; Define a lambda and call it with 5. |
|||
(macroexpand-1 '(->> 5 (fn [x] (* x x)))) |
|||
(fn [x] (* x x) 5) ; Define a lambda that returns 5 regardless.</syntaxhighlight> |
|||
The "thread first" macro (colloquially, the Thrush) provides a similar facility, wherein each expression becomes the first argument to the next. |
|||
<syntaxhighlight lang="clojure">(= (mod (inc 42) 7) |
|||
(-> 42 inc (mod 7)))</syntaxhighlight> |
|||
=={{header|CoffeeScript}}== |
|||
CoffeeScript allows loop constructs and conditionals to be written in a suffix manner. Loop constructs evaluate to an array containing the result of each iteration; conditionals evaluates either the true-case expression or the false-case one. |
|||
<syntaxhighlight lang="coffeescript">alert "hello" if true |
|||
alert "hello again" unless false # the same as the above; unless is a negated if. |
|||
idx = 0 |
|||
arr = (++idx while idx < 10) # arr is [1,2,3,4,5,6,7,8,9,10] |
|||
idx = 0 |
|||
arr = (++idx until idx is 10) # same as above; until is an inverted while.</syntaxhighlight> |
|||
=={{header|Common Lisp}}== |
|||
Lisp has a PROGN macro for evaluating a bunch of forms, such that the value(s) of the last one is yielded as the result of the PROGN. We can create a reversed analog of PROGN, inside which, we must write the syntax backwards: arguments first, then the operator. Furthermore, this rule is recursively applied to expressions. |
|||
''Note: unfortunately this is completely naive. To do this 100% right, we need a code walker, which is more complicated. However, code walkers are used in practice for hairy language transformation jobs, just not commonly so in daily Lisp programming. A code walker would let us imlement a more smarter version which would apply the transformation to forms which are evaluated, and not things like literal data. As it is, our macro also transforms literal data, making it impossible, for instance, to use the quote shorthand 'FORM. This stands for (QUOTE FORM) and of course, the macro will treat it as reversed syntax, transforming it to (FORM QUOTE). We could hack in a special case which recognized QUOTE, but then we do not know whether or not (QUOTE FORM) is in a context where it is being evaluated. That is why we need the code walker. It's best to use someone's well-tested, portable code-walker, since they are not trivial to write, and they have some implementation-specific parts (such as recognition of compiler-specific forms that come out of system macros or perhaps out of user-written nonportable code).'' |
|||
<syntaxhighlight lang="lisp">(eval-when (:compile-toplevel :load-toplevel :execute) |
|||
(defun unrev-syntax (form) |
|||
(cond |
|||
((atom form) form) |
|||
((null (cddr form)) form) |
|||
(t (destructuring-bind (oper &rest args) (reverse form) |
|||
`(,oper ,@(mapcar #'unrev-syntax args))))))) |
|||
(defmacro rprogn (&body forms) |
|||
`(progn ,@(mapcar #'unrev-syntax forms)))</syntaxhighlight> |
|||
Interactive test run: |
|||
<pre>$ clisp -q -i reverse.lisp |
|||
;; Loading file reverse.lisp ... |
|||
;; Loaded file reverse.lisp |
|||
[1]> (rprogn ((1 2 +) (3 4 +) *)) |
|||
21 |
|||
[2]> (rprogn (("not greater" print) ("greater" print) (1 2 >) if)) |
|||
"greater" |
|||
"greater" |
|||
[3]> (macroexpand '(rprogn (("not greater" print) ("greater" print) (1 2 >) if))) |
|||
(PROGN (IF (> 2 1) (PRINT "greater") (PRINT "not greater"))) ; |
|||
T |
|||
</pre> |
|||
Now here is a slightly more complicated version which more closely conforms to the idea given in this task. The operator is assumed to be the second-last element of a form. The last element of the form is the first argument, and the forms prior to the operator are the remaining arguments (in reverse order). These rules are recursively applied to each of the arguments, but not to the operator. A two element form is assumed to be (argument operator), and is rewritten to |
|||
(operator argument*) where argument* is the result of applying the unreversal to the argument: |
|||
<syntaxhighlight lang="lisp">(eval-when (:compile-toplevel :load-toplevel :execute) |
|||
(defun unrev-syntax (form) |
|||
(cond |
|||
((atom form) form) ;; atom: leave alone |
|||
((null (cdr form)) form) ;; one-element form: leave alone |
|||
((null (cddr form)) ;; two-element form: swap |
|||
(destructuring-bind (arg oper) form |
|||
`(,oper ,(unrev-syntax arg)))) |
|||
(t ;; two or more args: swap last two, add others in reverse |
|||
(destructuring-bind (arg1 oper &rest args) (reverse form) |
|||
`(,oper ,(unrev-syntax arg1) ,@(mapcar #'unrev-syntax args))))))) |
|||
(defmacro rprogn (&body forms) |
|||
`(progn ,@(mapcar #'unrev-syntax forms)))</syntaxhighlight> |
|||
<pre>[1]> (rprogn ((1 + 2) * (3 + 4))) |
|||
21 |
|||
[2]> (rprogn (("not equal" print) ("equal" print) if (1 = 2))) |
|||
"not equal" |
|||
"not equal" |
|||
[3]> (rprogn (("not equal" print) ("equal" print) if (1 = 1))) |
|||
"equal" |
|||
"equal" |
|||
[4]> (macroexpand '(rprogn (("not equal" print) ("equal" print) if (1 = 1)))) |
|||
(PROGN (IF (= 1 1) (PRINT "equal") (PRINT "not equal"))) ; |
|||
T |
|||
[5]> (macroexpand '(rprogn ((1 + 2) * (3 + 4)))) |
|||
(PROGN (* (+ 4 3) (+ 2 1))) ; |
|||
T</pre> |
|||
=={{header|D}}== |
|||
D enables a function to be called as if it were a method of its first argument. This feature often leads to natural syntax and readable, left-to-right expressions: |
|||
<syntaxhighlight lang="d">#!/usr/bin/rdmd |
|||
import std.algorithm; |
|||
void main() { |
|||
assert("Hello, World".length == 12); |
|||
assert("Cleanliness".startsWith("Clean")); |
|||
auto r = [1, 4, 2, 8, 5, 7] |
|||
.filter!(n => n > 2) |
|||
.map!(n => n * 2); |
|||
assert(r.equal([8, 16, 10, 14])); |
|||
}</syntaxhighlight> |
|||
=={{header|EchoLisp}}== |
|||
<syntaxhighlight lang="scheme"> |
|||
;; use reader macros to transform (a OP b) into (OP b a) |
|||
(lib 'match) |
|||
(define-macro invert-= (a <- b) (set! b a)) |
|||
(define-macro invert-IF (a 'IF b) (when b a)) |
|||
(define raining #f) |
|||
(#t <- raining) |
|||
raining |
|||
→ #t |
|||
('umbrella-need IF raining) |
|||
→ umbrella-need |
|||
(#f <- raining) |
|||
('umbrella-need IF raining) |
|||
→ #f |
|||
;; debug mode |
|||
(debug 3) |
|||
('umbrella-need IF raining) |
|||
💡 [0] invert-IF → ('umbrella-need IF raining) |
|||
compiled :: (#when raining 'umbrella-need) |
|||
</syntaxhighlight> |
|||
=={{header|Factor}}== |
|||
Since code is data in Factor, we can simply reverse it, transforming postfix into "prefix." |
|||
<syntaxhighlight lang="factor">1 1 + ! 2 |
|||
[ + 1 1 ] reverse call ! 2 |
|||
{ 1 2 3 4 5 } [ sq ] map ! { 1 4 9 16 25 } |
|||
[ map [ sq ] { 1 2 3 4 5 } ] reverse call ! { 1 4 9 16 25 }</syntaxhighlight> |
|||
In fact, using a Lisp-style macro, we can perform this transformation at parse time: |
|||
<syntaxhighlight lang="factor">MACRO: pre ( quot -- quot ) reverse ; |
|||
[ + 2 2 ] pre ! 4</syntaxhighlight> |
|||
Of course, this isn't true prefix because <code>+</code> retains its arity of <tt>2</tt>: |
|||
<syntaxhighlight lang="factor">[ + 3 + 2 2 ] pre ! 7</syntaxhighlight> |
|||
We can define a more accurate prefix macro for addition and subtraction in terms of <code>reduce</code>: |
|||
<syntaxhighlight lang="factor">MACRO: pre ( quot -- quot ) 1 cut swap [ 0 ] dip reduce 1quotation ; |
|||
[ + 1 2 3 4 5 ] pre ! 15</syntaxhighlight> |
|||
Additionally, using parsing words, we can add any syntax we like. The <code>infix</code> vocabulary is an example of this: |
|||
<syntaxhighlight lang="factor">USE: infix |
|||
[infix |
|||
5*(1+1) ! 10 |
|||
infix]</syntaxhighlight> |
|||
=={{header|Fortran}}== |
|||
Leaving aside those who think that Fortran is inherently backward, assignment in Fortran is firmly right-to-left in the form <code>''variable'' = ''expression''</code> where the ''expression'' is computed in accordance with the precedence rules and the resulting value is assigned to the ''variable''. |
|||
However, assignment-style constructions appear inside the INQUIRE statement as in <syntaxhighlight lang="fortran"> INQUIRE(FILE = FILENAME(1:L), EXIST = MAYBE, ERR = 666, IOSTAT = RESULT) </syntaxhighlight> |
|||
Here, a logical variable MAYBE is to receive the value of whether or not the disc file named in FILENAME(1:L) exists, and integer variable RESULT contains an error code, zero if all went well - the file name may not be correctly formed, for example. Thus, FILE is receiving a value right-to-left on entry to the statement, while MAYBE and RESULT receive values left-to-right on exit from the statement. Despite appearances, <code>ERR = 666</code> is not an assignment statement; 666 is not an integer, it is a statement label to which execution will jump should an error arise. Similar arrangements apply for the file OPEN and CLOSE statements. |
|||
There is no deviationism with the workings of IF-statements. |
|||
=={{header|FreeBASIC}}== |
|||
FreeBASIC has nothing like this built into the language. |
|||
The nearest we can get is to define macros which reverse the order of the arguments: |
|||
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64 |
|||
#Define ThenIf(a, b) If b Then a |
|||
#Define InvertAssign(a, b) b = a |
|||
Dim As Boolean needUmbrella = False, raining = True |
|||
ThenIf(needUmbrella = True, raining = True) |
|||
Print "needUmbrella = "; needUmbrella |
|||
Dim As Integer b = 0, a = 3 |
|||
InvertAssign(a, b) |
|||
Print "b is"; b |
|||
Sleep</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
needUmbrella = true |
|||
b is 3 |
|||
</pre> |
|||
=={{header|Fōrmulæ}}== |
|||
{{FormulaeEntry|page=https://formulae.org/?script=examples/Inverted_syntax}} |
|||
'''Inverted syntax with conditional expressions''' |
|||
The following is how is visualized the common IF expression: |
|||
[[File:Fōrmulæ - Inverted syntax 01.png]] |
|||
The following is the visualization of the inverted IF expression. Notice that they are different expressions, in order that they can be visualized in different form, but they reduce the same way. |
|||
[[File:Fōrmulæ - Inverted syntax 02.png]] |
|||
'''Inverted syntax with assignment''' |
|||
The assignment expression does not have an inverted form. |
|||
=={{header|Go}}== |
|||
The closest Go can get to inverted syntax for conditionals is to define a new type ('ibool' say) based on the built-in 'bool' type and then define a method ('iif' say) on the new type which takes the place of the traditional 'if'. |
|||
Simulating inverted syntax with assignment is not possible. |
|||
<syntaxhighlight lang="go">package main |
|||
import "fmt" |
|||
type ibool bool |
|||
const itrue ibool = true |
|||
func (ib ibool) iif(cond bool) bool { |
|||
if cond { |
|||
return bool(ib) |
|||
} |
|||
return bool(!ib) |
|||
} |
|||
func main() { |
|||
var needUmbrella bool |
|||
raining := true |
|||
// normal syntax |
|||
if raining { |
|||
needUmbrella = true |
|||
} |
|||
fmt.Printf("Is it raining? %t. Do I need an umbrella? %t\n", raining, needUmbrella) |
|||
// inverted syntax |
|||
raining = false |
|||
needUmbrella = itrue.iif(raining) |
|||
fmt.Printf("Is it raining? %t. Do I need an umbrella? %t\n", raining, needUmbrella) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Is it raining? true. Do I need an umbrella? true |
|||
Is it raining? false. Do I need an umbrella? false |
|||
</pre> |
|||
=={{header|Haskell}}== |
|||
Because Haskell is an expression-based pure functional language, this cannot be defined in the general case, because not every expression has a type with a null-like default value that can be inferred. |
|||
However, for the common case where you want to perform a certain action only when some condition holds, you can define a simple binary operator: |
|||
<syntaxhighlight lang="haskell">when :: Monad m => m () -> Bool -> m () |
|||
action `when` condition = if condition then action else return () |
|||
</syntaxhighlight> |
|||
Example usage: |
|||
<pre> |
|||
Prelude> putStrLn "It's true." `when` False |
|||
Prelude> putStrLn "It's true." `when` True |
|||
It's true. |
|||
Prelude> |
|||
</pre> |
|||
---- |
|||
Haskell has a feature that can be considered "inverted" syntax (although it is not one of the types listed in the description of the task): The definition of local variables to be used in a function can be placed in a <code>where</code> clause that comes ''after'' the function body: |
|||
<syntaxhighlight lang="haskell">func a b x = (x + y) / y |
|||
where y = a * b</syntaxhighlight> |
|||
This is in contrast to <code>let</code> expressions, where the definition of local variables comes before the scope that uses them: |
|||
<syntaxhighlight lang="haskell">func a b x = |
|||
let y = a * b in |
|||
(x + y) / y</syntaxhighlight> |
|||
---- |
|||
The standard ''Data.Bool'' module defines a ''bool'' function. |
|||
'''bool x y p''' evaluates to '''x''' when '''p''' is '''False''', and evaluates to '''y''' when '''p''' is '''True'''. |
|||
<syntaxhighlight lang="haskell">import Data.Bool (bool) |
|||
main :: IO () |
|||
main = do |
|||
let raining = False |
|||
putStrLn $ bool "No need" "UMBRELLA !" raining |
|||
putStrLn $ flip bool "No need" "UMBRELLA !" raining |
|||
putStrLn "\n--------\n" |
|||
mapM_ putStrLn $ |
|||
[bool, flip bool] |
|||
<*> ["No need"] |
|||
<*> ["UMBRELLA !"] |
|||
<*> [raining, not raining]</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>No need |
|||
UMBRELLA ! |
|||
-------- |
|||
No need |
|||
UMBRELLA ! |
|||
UMBRELLA ! |
|||
No need</pre> |
|||
=={{header|Icon}} and {{header|Unicon}}== |
|||
Icon and Unicon can use [[Icon%2BUnicon/Intro#Conjunction.2C_yielding_a_different_result|expression conjunctions that select different sub-expression results]] to create this effect. |
|||
<syntaxhighlight lang="icon">procedure main() |
|||
raining := TRUE := 1 # there is no true/false null/non-null will do |
|||
if \raining then needumbrella := TRUE # normal |
|||
needumbrella := 1(TRUE, \raining) # inverted (choose sub-expression 1) |
|||
end</syntaxhighlight> |
|||
=={{header|J}}== |
|||
J tries to minimize syntax and control structures. However, they are present. |
|||
For control structures, "traditional conditional structures" are traditional (control structures implemented using keywords such as <code>if.</code> are not inverted). But J offers some alternatives which are inverted (operations such as <code>^:</code>) or both (operations such as <code>*</code> (multiplication) can be used as inverted conditional structures or as traditional conditional structures, depending on whether you place the boolean test on the left or the right side). See [[Conditional_Structures/J]] for some examples. |
|||
Note also that simple, regular iteration without control structures is fundamental to the language (and turns data selection operations, including indexing, into conditional structures). But no special syntax is present for these cases so it can be neither traditional nor inverted. |
|||
=={{header|Java}}== |
|||
The closest Java comes to placing an action before a condition is with <pre>do ... while(condition);</pre> |
|||
=={{header|jq}}== |
|||
jq's syntax for associating a value with a variable is "inverted": the expression for associating a value, v, with a variable, $x, is: |
|||
<syntaxhighlight lang="jq">v as $x</syntaxhighlight> |
|||
Note, however, that there is limited support for the conventional "target = value" syntax in the context of JSON objects and arrays, but the semantics is purely functional. <br> |
|||
For example, if o is {"a": 1}, then the expression: |
|||
<syntaxhighlight lang="jq">o["a"] = 2 |
|||
# or equivalently: o.a = 2</syntaxhighlight> emits another object equal to {"a": 2}. |
|||
=={{header|Julia}}== |
|||
{{works with|Julia|0.6}} |
|||
Can be easily implemented as a macro: |
|||
<syntaxhighlight lang="julia">macro inv(expr, cond) |
|||
cond isa Expr && cond.head == :if || throw(ArgumentError("$cond is not an if expression")) |
|||
cond.args[2] = expr |
|||
return cond |
|||
end |
|||
@inv println("Wow! Lucky Guess!") if true else println("Not!") end</syntaxhighlight> |
|||
=={{header|Koka}}== |
|||
Using the byref function and infix operators we can get both inverted assignments as well as inverted conditionals in Koka! However, the branch to the conditional is evaluated prior to the condition unless you explicitly delay it or accept a closure. |
|||
<syntaxhighlight lang="koka"> |
|||
fun (=:)(c: c, v: local-var<h, c>): <local<h>> () |
|||
v := c |
|||
fun (?)(c: c, b: bool): e maybe<c> |
|||
if b then Just(c) else Nothing |
|||
fun main() |
|||
var x := 4 |
|||
6 =: std/core/types/byref(x) |
|||
x.println |
|||
val res = "Yes" ? True |
|||
match res |
|||
Just(a) -> println(a) |
|||
Nothing -> throw("Nothing") |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
6 |
|||
Yes |
|||
</pre> |
|||
=={{header|Kotlin}}== |
|||
Kotlin can get close to an inverted 'if' syntax by defining an infix function - 'iif' say. However, there doesn't appear to be a way to mimic inverted assignment. |
|||
<syntaxhighlight lang="scala">// version 1.0.6 |
|||
infix fun Boolean.iif(cond: Boolean) = if (cond) this else !this |
|||
fun main(args: Array<String>) { |
|||
val raining = true |
|||
val needUmbrella = true iif (raining) |
|||
println("Do I need an umbrella? ${if(needUmbrella) "Yes" else "No"}") |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Do I need an umbrella? Yes |
|||
</pre> |
|||
=={{header|Latitude}}== |
|||
Latitude, by default, does not support inverted conditionals, as its two primary means of conditional branching both involve the condition first. |
|||
<syntaxhighlight lang="latitude">local 'raining = True. |
|||
local 'needUmbrella = False. |
|||
if (raining) then { |
|||
needUmbrella = True. |
|||
} else {}. |
|||
{ raining. } ifTrue { |
|||
needUmbrella = True. |
|||
}.</syntaxhighlight> |
|||
However, such constructs can easily be added to the language. |
|||
<syntaxhighlight lang="latitude">#'Method when := { |
|||
localize. |
|||
if ($1) then { |
|||
this. |
|||
} else { }. |
|||
}. |
|||
#'Method unless := { |
|||
#'self when ($1 not). |
|||
}. |
|||
;; Example usage |
|||
{ needUmbrella = True. } when (raining). |
|||
{ needUmbrella = True. } unless (raining not).</syntaxhighlight> |
|||
Likewise, inverted assignment syntax is not supported natively, but it can be approximated in-language, using a definition similar to that of the built-in <code>local=</code>. |
|||
<syntaxhighlight lang="latitude">global let= := { self slot ($2) = #'$1. }. |
|||
local 'a = 6. |
|||
println: a. ;; 6 |
|||
let 6 = 'b. |
|||
println: b. ;; 6</syntaxhighlight> |
|||
=={{header|Lua}}== |
|||
In general, Lua does not support any ''truly'' inverted syntax, though there are some metamethod techniques and taking advantage of syntactic sugar that perhaps at least give the ''illusion'' that syntax has been inverted. Here, calling a library method passing a table, versus the table itself calling as if its own method, equivalently: |
|||
<syntaxhighlight lang="lua">a = {1,3,5,4,2} -- a "plain" table |
|||
table.sort(a) -- library method passing a as param |
|||
print(table.concat(a)) -- and again --> "12345" |
|||
b = {1,3,5,4,2} -- a "plain" table, so far.. |
|||
setmetatable(b, {__index=table}) -- ..but now "meta-decorated" |
|||
b:sort() -- syntax sugar passes b as "self" |
|||
print(b:concat()) -- and again --> "12345"</syntaxhighlight> |
|||
=={{header|M2000 Interpreter}}== |
|||
There is no way to have inverted syntax for conditionals, except for using lambda functions. Three more things we can do. One to invert the way we call a module, passing statements before calling the module. The Second by using Let we make a Push and then a Read, so first evaluated the right expression and then the left. Here we change a global variable in the right expression and we change the index of array where we set the returned value from function. |
|||
The third one is more complicated. We make a callback function which act as code of a module, with same scope, and use a module to check condition before we call the callback function |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
expr=lambda ->{ |
|||
Print "ok" |
|||
} |
|||
ifrev=lambda (dothis, cond) ->{ |
|||
if cond then call dothis() |
|||
} |
|||
a=1 |
|||
call ifrev(expr, a=1) |
|||
\\ on module call |
|||
Module Subtract (a, b) { |
|||
Push a-b |
|||
} |
|||
Module PrintTop { |
|||
Print Number |
|||
} |
|||
Subtract 10, 3 : PrintTop |
|||
\\ pushing before calling in reverse order |
|||
Push 3, 10 : Subtract : PrintTop |
|||
\\ Before call PrintTop any parameter send to stack |
|||
\\ So this works ok |
|||
PrintTop 1000 |
|||
\\ on assignment |
|||
Dim A(5)=1 |
|||
Global n=2 |
|||
Function AddOne (x) { |
|||
n++ |
|||
=x |
|||
} |
|||
\\ Execution of left expression, then right expression |
|||
A(n)=AddOne(5) |
|||
Print A(n-1)=5, n=3 |
|||
\\ Execution of right expression, then left expression |
|||
Let A(n)=AddOne(15) |
|||
Print A(n)=15, n=4 |
|||
\\ This statement.. |
|||
Let X=1, Y=2 |
|||
\\ executed like these |
|||
Push 2, 1 : Read X, Y |
|||
\\ This is the CallBack way |
|||
Module ExecCond { |
|||
Read &callback(), cond |
|||
if cond then call callback() |
|||
} |
|||
x=1 |
|||
\\ this aa() is a function but when we call it after transforming from Lazy$() |
|||
\\ act as part of module so we see x, and alter it |
|||
Function aa { |
|||
x++ |
|||
} |
|||
a=1 |
|||
ExecCond Lazy$(&aa()), A=1 |
|||
Print x=2 |
|||
</syntaxhighlight> |
|||
=={{header|m4}}== |
|||
We [[extend your language|extend our language]] with a new macro, <code>thenif</code>, |
|||
to invert the arguments to the builtin macro, <code>ifelse</code>. |
|||
<syntaxhighlight lang="m4">define(`thenif', `ifelse($2, $3, `$1')')dnl |
|||
dnl |
|||
ifelse(eval(23 > 5), 1, 23 is greater than 5) |
|||
ifelse(eval(23 > 5), 0, math is broken) |
|||
thenif(23 is greater than 5, eval(23 > 5), 1) |
|||
thenif(math is broken, eval(23 > 5), 0)</syntaxhighlight> |
|||
This example outputs these four lines. |
|||
Math was not broken, so two lines are empty. |
|||
<pre>23 is greater than 5 |
|||
23 is greater than 5 |
|||
</pre> |
|||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
|||
Traditional form: |
|||
<syntaxhighlight lang="mathematica">a = 4 |
|||
->4 |
|||
b = 5 |
|||
->5 |
|||
If[1<2, |
|||
Print["This was expected"] |
|||
] |
|||
->This was expected</syntaxhighlight> |
|||
Inversion of syntax: |
|||
<pre>Unprotect["="]; SetAttributes[Set2, HoldAll]; Set2[a_, b_] := Set[b, a] |
|||
<< Notation`; Notation[ParsedBoxWrapper[RowBox[{"x_", "=","y_"}]] |
|||
\[DoubleLongLeftRightArrow] |
|||
ParsedBoxWrapper[RowBox[{" ", RowBox[{"Set2", "[", RowBox[{"x_", ",", "y_"}], "]"}]}]]] |
|||
2 = c |
|||
->2 |
|||
3 = d |
|||
->3 |
|||
Unprotect["If"];SetAttributes[If2,HoldAll];If2[a_,b_]:=If[b,a] |
|||
Notation[If[x_,y_] \[DoubleLongLeftRightArrow] If2[x_,y_]] |
|||
If[Print["This was expected"], |
|||
1<2 |
|||
] |
|||
->This was expected</pre> |
|||
=={{header|Mercury}}== |
|||
For Mercury, order rarely matters. |
|||
Just as programmers in most languages take care to order their function definitions or their method definitions for clarity and emphasis, while knowing that it's all the same to the compiler, Mercury programmers can do this also in the bodies of functions. |
|||
These two clauses are exactly the same: |
|||
<syntaxhighlight lang="mercury">:- pred progress(int::in, int::in, int::out, int::out) is det. |
|||
progress(Past, Future, At, Total) :- |
|||
At = Past + 1, |
|||
Total = Past + Future. |
|||
progress(Past, Future, At, Total) :- |
|||
Past + Future = Total, |
|||
Past + 1 = At.</syntaxhighlight> |
|||
Order doesn't matter even when a data dependency tells you (and Mercury's compiler) what the order of evaluation must be: |
|||
<syntaxhighlight lang="mercury">:- func example(int) = string. |
|||
example(N) = S :- |
|||
from_int(N) = S0, |
|||
pad_left(S0, '0', 3, S). |
|||
example(N) = S :- |
|||
pad_left(S0, '0', 3, S), |
|||
from_int(N) = S0.</syntaxhighlight> |
|||
Data dependencies are most obvious when state is threaded through a clause: |
|||
<syntaxhighlight lang="mercury">main(IO0, IO) :- |
|||
io.write_string("Hello, ", IO0, IO1), |
|||
io.write_string("world!\n", IO1, IO). |
|||
main(!IO) :- |
|||
io.write_string("Hello, ", !IO), |
|||
io.write_string("world!\n", !IO).</syntaxhighlight> |
|||
The io.write_string/2's in the first example could be written in either order and the result would be the same, as the "world!\n" can't be written until the "Hello, " provides the IO1. |
|||
Order matters in the second example, however, as it uses [http://www.mercury.csse.unimelb.edu.au/information/doc-release/mercury_ref/State-variables.html#State-variables state variables]. |
|||
The order is still enforced by a data dependency, so |
|||
<syntaxhighlight lang="mercury">main(!IO) :- |
|||
io.write_string(X, !IO), io.nl(!IO), |
|||
some_long_uninteresting_thing(X). |
|||
% this is the same: |
|||
main(!IO) :- |
|||
some_long_uninteresting_thing(X), |
|||
io.write_string(X, !IO), io.nl(!IO). |
|||
% but this is different! |
|||
main(!IO) :- |
|||
io.nl(!IO), io.write_string(X, !IO), |
|||
some_long_uninteresting_thing(X).</syntaxhighlight> |
|||
=={{header|Metafont}}== |
|||
Although there is an assignment operator, you can also define values of variables by equations, such as: |
|||
<syntaxhighlight lang="metafont">x=6; |
|||
7=y;</syntaxhighlight> |
|||
Therefore it can be done both ways. |
|||
=={{header|Nim}}== |
|||
Inverted syntax in Nim can be achieved through the use of templates as operators: |
|||
<syntaxhighlight lang="nim">#-- |
|||
# if statements |
|||
#-- |
|||
template `?`(expression, condition) = |
|||
if condition: |
|||
expression |
|||
let raining = true |
|||
var needUmbrella: bool |
|||
# Normal syntax |
|||
if raining: needUmbrella = true |
|||
# Inverted syntax |
|||
(needUmbrella = true) ? (raining == true) |
|||
#-- |
|||
# Assignments |
|||
#-- |
|||
template `~=`(right, left) = |
|||
left = right |
|||
var a = 3 |
|||
# Normal syntax |
|||
a = 6 |
|||
# Inverted syntax |
|||
6 ~= a</syntaxhighlight> |
|||
=={{header|Oforth}}== |
|||
Oforth uses RPN so some forms a partially (or totally) inverted : |
|||
6 -> a : Push 6 on the stack and set the top of the stack as value of local variable a (top of the stack is consumed) |
|||
6 := a : Push 6 on the stack and set the top of the satck as value of attribute a (top of the stack is consumed). |
|||
raining ifTrue: [ true ->needumbrella ] |
|||
=={{header|OxygenBasic}}== |
|||
Macros may have localised scope, so they can be safely deployed as HumptyDumpty words. |
|||
<syntaxhighlight lang="oxygenbasic"> |
|||
macro cond(a,c) {c then a} |
|||
macro store(b,a) {a=b} |
|||
sys a,c=10 |
|||
if c>4 then a=4 |
|||
'INVERTED SYNTAX FORMS: |
|||
cond a=40, if c>4 |
|||
store 4,a |
|||
'COMBINED: |
|||
cond store(5,a), if c>4 |
|||
</syntaxhighlight> |
|||
=={{header|PARI/GP}}== |
|||
{{works with|PARI/GP|version 2.4.2 and above}} |
|||
GP does not include a syntax-inverted if, but that can be defined using closures. |
|||
<syntaxhighlight lang="parigp">fi(f, condition)=if(condition,f()); |
|||
if(raining, print("Umbrella needed")) |
|||
fi(->print("Umbrella needed"), raining)</syntaxhighlight> |
|||
PARI can also be used to implement it more directly in GP. |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Perl already has that: |
|||
<lang perl>if ($guess == 6) { print "Wow! Lucky Guess!"; }; # Traditional syntax |
|||
<syntaxhighlight lang="perl">if ($guess == 6) { print "Wow! Lucky Guess!"; }; # Traditional syntax |
|||
print 'Wow! Lucky Guess!' if $guess == 6; # Inverted syntax (note missing braces and parens) |
|||
unless ($guess == 6) { print "Sorry, your guess was wrong!"; } # Traditional syntax |
|||
print 'Huh! You Guessed Wrong!' unless $guess == 6; # Inverted syntax</syntaxhighlight> |
|||
</lang> |
|||
Inverted syntax can also be used with the ternary operator. |
|||
However this may produce different results to the traditional syntax form because when inverted syntax is used, we are effectively making an assignment to a ternary expression. so in the following example code, instead of the assignment being made to variable a (as it is in the traditional syntax form), the inverted syntax form will cause assignment to be made to either b or c, depending on value of the ok variable: |
|||
<syntaxhighlight lang="perl"># Note that the results obtained by the inverted syntax form |
|||
# may produce differing results from the traditional syntax form |
|||
$a = $ok ? $b : $c; # Traditional syntax |
|||
($ok ? $b : $c) = $a; # Inverted syntax</syntaxhighlight> |
|||
We can also emulate inverted syntax for scalar assignment by creating a function as follows: |
|||
<syntaxhighlight lang="perl">sub assign { $_[1] = $_[0] } |
|||
$a = $b; # Traditional syntax |
|||
assign $b, $a; # Inverted syntax</syntaxhighlight> |
|||
Inverted list assignment is not possible because it prevents arrays from flattening. |
|||
=={{header|Phix}}== |
|||
original... the got still you've as long as ,itself compile/run to used be can This |
|||
<!--<syntaxhighlight lang="phix">(notonline)--> |
|||
<span style="color: #008080;">if</span> <span style="color: #008080;">end</span> |
|||
<span style="color: #0000FF;">(&</span><span style="color: #008000;">"test.exw"</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span><span style="color: #000000;">cl</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">system</span> |
|||
<span style="color: #008080;">then</span> <span style="color: #0000FF;">></span><span style="color: #000000;">2</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cl</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">length</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #0000FF;">(&</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pgm</span><span style="color: #0000FF;">)</span><span style="color: #000000;">mung</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"test.exw"</span><span style="color: #0000FF;">)</span><span style="color: #000000;">write_file</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> |
|||
<span style="color: #000000;">write_file</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> <span style="color: #008080;">include</span> |
|||
<span style="color: #0000FF;">([$]</span><span style="color: #000000;">cl</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">get_text</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pgm</span> <span style="color: #004080;">string</span> |
|||
<span style="color: #0000FF;">()</span><span style="color: #7060A8;">command_line</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">cl</span> <span style="color: #004080;">sequence</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #008080;">end</span> |
|||
<span style="color: #0000FF;">(</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">join</span> <span style="color: #008080;">return</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #008080;">end</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">nup</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rip</span><span style="color: #0000FF;">,((([</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">substitute_all</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span><span style="color: #000000;">lines</span> <span style="color: #008080;">do</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">length</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">=</span><span style="color: #000000;">i</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #0000FF;">((</span><span style="color: #008000;">"\r\n"</span><span style="color: #0000FF;">,(</span><span style="color: #000000;">rip</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pun</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pgm</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">=</span><span style="color: #000000;">lines</span> <span style="color: #004080;">sequence</span> |
|||
<span style="color: #0000FF;">(</span><span style="color: #000000;">pgm</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">)</span><span style="color: #000000;">mung</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">,(</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" -<>{}@! "</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">join_by</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">split</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rip</span> <span style="color: #008080;">constant</span> |
|||
<span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">,(</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-,=][)("</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">join_by</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">split</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nup</span> <span style="color: #008080;">constant</span> |
|||
<span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">,(</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"-,=[]()"</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">join_by</span><span style="color: #0000FF;">)</span><span style="color: #7060A8;">split</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pun</span> <span style="color: #008080;">constant</span> |
|||
<span style="color: #008080;">js without</span> |
|||
<span style="color: #000000;">demo</span><span style="color: #0000FF;">\</span><span style="color: #000000;">rosetta</span><span style="color: #0000FF;">\</span><span style="color: #000000;">inverted_syntax</span><span style="color: #0000FF;">.</span><span style="color: #000000;">exw</span> <span style="color: #000080;font-style:italic;">--</span> |
|||
<!--</syntaxhighlight>--> |
|||
I should note that "if length(cl)>2 then" gets away by the skin of its teeth and would break were it written "if length(cl) > 2 then".<br> |
|||
... and here is the original, which can be used to first create and then re-run to compile/run the above, in fact destroying/restoring/recreating it in the latter process. |
|||
<!--<syntaxhighlight lang="phix">(notonline)--> |
|||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\inverted_syntax.exw</span> |
|||
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">pun</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join_by</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"()[]=,-"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">nup</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join_by</span><span style="color: #0000FF;">(</span><span style="color: #008000;">")(][=,-"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">rip</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join_by</span><span style="color: #0000FF;">(</span><span style="color: #008000;">" <>{}@!- "</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"*"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">mung</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">pgm</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pgm</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pun</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rip</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"\r\n"</span><span style="color: #0000FF;">))</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> <span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]))),</span><span style="color: #000000;">rip</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nup</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">cl</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">command_line</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">pgm</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_text</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cl</span><span style="color: #0000FF;">[$])</span> |
|||
<span style="color: #008080;">include</span> <span style="color: #000000;">write_file</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span> |
|||
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">write_file</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"test.exw"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mung</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pgm</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cl</span><span style="color: #0000FF;">)></span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #7060A8;">system</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cl</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]&</span><span style="color: #008000;">"test.exw"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<!--</syntaxhighlight>--> |
|||
=={{header|PicoLisp}}== |
|||
We define a read macro for reverted syntax |
|||
<syntaxhighlight lang="picolisp">(de rv Prg |
|||
(append (last Prg) (head -1 Prg)) )</syntaxhighlight> |
|||
Test: |
|||
<pre>(de needUmbrella (Raining) |
|||
`(rv # Inverted syntax |
|||
(on *NeedUmbrella) |
|||
(println 'Need 'an 'umbrella) |
|||
(when Raining) ) ) |
|||
(de keepUmbrella (Raining) |
|||
`(rv # Inverted syntax |
|||
(on *KeepUmbrella) |
|||
(println 'Still 'need 'an 'umbrella) |
|||
(while Raining) ) )</pre> |
|||
{{out}} |
|||
<pre>: (pp 'needUmbrella) |
|||
(de needUmbrella (Raining) |
|||
(when Raining # Traditional syntax |
|||
(on *NeedUmbrella) |
|||
(println 'Need 'an 'umbrella) ) ) |
|||
: (pp 'keepUmbrella) |
|||
(de keepUmbrella (Raining) |
|||
(while Raining # Traditional syntax |
|||
(on *KeepUmbrella) |
|||
(println 'Still 'need 'an 'umbrella) ) )</pre> |
|||
=={{header|PowerShell}}== |
|||
The PowerShell syntax for an 'if' statement is very normal: |
|||
<syntaxhighlight lang="powershell"> |
|||
if ((Get-Date 5/27/2016).DayOfWeek -eq "Friday") {"Thank God it's Friday!"} |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
Thank God it's Friday! |
|||
</pre> |
|||
The order of the condition and expression can be easily reversed (with a slight change in syntax): |
|||
<syntaxhighlight lang="powershell"> |
|||
function Action ([scriptblock]$Expression, [Alias("if")][bool]$Test) |
|||
{ |
|||
if ($Test) {&$Expression} |
|||
} |
|||
Set-Alias -Name say -Value Action |
|||
say {"Thank God it's Friday!"} -if (Get-Date 5/27/2016).DayOfWeek -eq "Friday" |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
Thank God it's Friday! |
|||
</pre> |
|||
=={{header|Prolog}}== |
|||
Prolog programs are made up of facts and rules. Facts are considered "true" if they are provable from the source code and "false" otherwise. The rules for proving new facts are described using "horn clauses" which are backwards "if" statements: the truth value of the second part becomes the truth value of the first part. |
|||
The facts themselves are usually expressed using "functors" involving parentheses, with the constant in front of the parentheses naming some property which applies to one or more items inside. As a result, they sometimes kind of look like backwards "is" statements. |
|||
<syntaxhighlight lang="prolog">% Dracula is a vampire. |
|||
% Also, you become a vampire if someone who is a vampire bites you. |
|||
vampire(dracula). |
|||
vampire(You) :- bites(Someone, You), vampire(Someone). |
|||
% Oh no! Dracula just bit Bob... |
|||
bites(dracula, bob).</syntaxhighlight> |
|||
{{out}} |
|||
We load the source code into the interpreter and ask whether Alice and Bob are vampires... |
|||
<pre> |
|||
?- vampire(alice). |
|||
false. |
|||
?- vampire(bob). |
|||
true . |
|||
</pre> |
|||
=={{header|Python}}== |
|||
<syntaxhighlight lang="python">x = truevalue if condition else falsevalue</syntaxhighlight> |
|||
<syntaxhighlight lang="python">with open("file.txt") as f: |
|||
something(f)</syntaxhighlight> |
|||
=={{header|Qi}}== |
|||
<syntaxhighlight lang="qi"> |
|||
(define set-needumbrella |
|||
Raining -> (set needumbrella true) where (= true Raining) |
|||
Raining -> (set needumbrella false) where (= false Raining)) |
|||
(define set-needumbrella |
|||
Raining -> (if (= true Raining) |
|||
(set needumbrella true) |
|||
(set needumbrella false))) |
|||
Alternatives: |
|||
(define set-needumbrella |
|||
Raining -> (set needumbrella true) where Raining |
|||
Raining -> (set needumbrella false)) |
|||
(define set-needumbrella |
|||
Raining -> (if Raining |
|||
(set needumbrella true) |
|||
(set needumbrella false))) |
|||
(define set-needumbrella |
|||
true -> (set needumbrella true) |
|||
false -> (set needumbrella false)) |
|||
(define set-needumbrella |
|||
A -> (set needumbrella A)) |
|||
</syntaxhighlight> |
|||
=={{header|Quackery}}== |
|||
A Quackery program consists of numbers, words, and nests, collectively referred to as items. A nest is a sequence of zero or more items. Items are evaluated sequentially. |
|||
Some words can alter this sequential behaviour. <code>if</code> for example, causes the item following it to be skipped if the number on the top of data stack (henceforth just "the stack") is zero (i.e. false.) |
|||
So, given that the word <code>raining</code> returns a boolean (i.e. 0 or 1) indicating whether it is raining or not, and the word <code>use-umbrella</code> deploys an umbrella, the usual syntax would be <code>raining if use-umbrella</code>. |
|||
The word <code>'</code> alters the sequential flow by causing the item following it to be placed on the stack rather than being evaluated. The word <code>do</code> causes the item on the top of the stack to be evaluated. So we could define a new word, <code>if.1</code> with |
|||
<pre>[ swap do iff do else drop ] is if.1</pre> |
|||
which would allow us to use the syntax <code>' raining ' use-umbrella if.1</code>. (<code>iff</code> conditionally skips over two items, <code>else</code> unconditionally skips over one item.) |
|||
<code>'</code> is defined using the meta-control flow operator <code>]'[</code> thus: <code>[ ]'[ ] is '</code> Meta-control flow operators grant their behaviour to the word that calls them. So if we wanted the syntax <code>' use-umbrella if.2 raining</code> we could define <code>if.2</code> with |
|||
<pre>[ ]'[ do iff do else drop ] is if.2</pre> |
|||
Other syntaxes can be achieved by the judicious use of <code>'</code> and <code>]'[</code>. To demonstrate just one that avoids the use of <code>if ...</code> or <code>iff ... else ...</code> entirely, one could define a word <code>ifelse</code> as |
|||
<pre>[ not ]'[ nested ]'[ nested join swap peek do ] is ifelse</code></pre> |
|||
This would have the syntax <code>raining ifelse use-umbrella use-sunscreen</code> (for an appropriate definition of <code>use-sunscreen</code>.) |
|||
Quackery does not have variables, so there is not exact equivalent to assignment, but it does have ancillary stacks which can be used in a variable-like manner. <code>temp</code> is a predefined ancillary stack, and an item can be moved from the stack to it with the phrase <code>temp put</code>. As with the previous examples, <code>]'[</code> can be used to vary the syntax. |
|||
=={{header|R}}== |
|||
This can be done with a simple function. |
|||
<syntaxhighlight lang="r">do.if <- function(expr, cond) if(cond) expr</syntaxhighlight> |
|||
Because R evaluates function arguments lazily, "expr" is never evaluated unless "cond" evaluates to true. |
|||
<syntaxhighlight lang="r">do.if(print("Wow! Lucky Guess!"), guess==6)</syntaxhighlight> |
|||
If you do not want to state "do.if" first, you can define an infix operator (any function whose name is bracketed in percent signs is treated as an infix operator), however custom infix operators have higher precedence than comparisons, so will usually require putting parentheses around the test. |
|||
<syntaxhighlight lang="r">`%if%` <- function(expr, cond) if(cond) expr |
|||
print("Wow! Lucky Guess!") %if% (guess==6)</syntaxhighlight> |
|||
=={{header|Racket}}== |
|||
Normally, all syntactic forms and functions are in prefix notation. |
|||
However, two <tt>.</tt>s allow infix notation in some cases. |
|||
<syntaxhighlight lang="racket"> |
|||
#lang racket |
|||
(when #t (displayln "true")) |
|||
((displayln "true") . when . #t) |
|||
(define a 6) |
|||
(set! a 5) |
|||
(a . set! . 6) |
|||
</syntaxhighlight> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
Raku has statement modifiers: |
|||
<syntaxhighlight lang="raku" line>if $guess == 6 { say "Wow! Lucky Guess!" } # Traditional |
|||
say 'Wow! Lucky Guess!' if $guess == 6; # Inverted |
|||
unless $guess == 6 { say "Huh! You Guessed Rong!" } # Traditional |
|||
say 'Huh! You Guessed Rong!' unless $guess == 6; # Inverted</syntaxhighlight> |
|||
Raku can also invert the syntax of loops: |
|||
<syntaxhighlight lang="raku" line>while $i { --$i } |
|||
--$i while $i; |
|||
until $x > 10 { $x++ } |
|||
$x++ until $x > 10; |
|||
for 1..10 { .say if $_ %% 2 } |
|||
.say if $_ %% 2 for 1..10; # list comprehension</syntaxhighlight> |
|||
Raku has a system of metaoperators that modify the characteristics of normal operators. Among these is the <tt>R</tt> metaoperator, which is able to reverse the arguments of most infix operators (including user-defined ones). |
|||
So a reversed assignment is easy to write: |
|||
<syntaxhighlight lang="raku" line>42 R= $_; say $_; # prints 42</syntaxhighlight> |
|||
Since, much like list operators, assignment loosens the precedence of the following expression to allow comma lists, reverse assignment of a list requires parens where the normal assignment would not: |
|||
<syntaxhighlight lang="raku" line>my @a = 1,2,3; |
|||
(1,2,3) R= my @a;</syntaxhighlight> |
|||
However, generally in that case you'd use a feed operator anyway, which is like an object pipe, but unlike Unix pipes works in either direction: |
|||
<syntaxhighlight lang="raku" line>my @a <== 1,2,3; |
|||
1,2,3 ==> my @a;</syntaxhighlight> |
|||
We think this is much more readable than a reversed assignment. |
|||
One other interesting inversion is the ability to put the conditional of a repeat loop at either end, with identical test-after semantics: |
|||
<syntaxhighlight lang="raku" line>repeat { |
|||
$_ = prompt "Gimme a number: "; |
|||
} until /^\d+$/; |
|||
repeat until /^\d+$/ { |
|||
$_ = prompt "Gimme a number: "; |
|||
}</syntaxhighlight> |
|||
This might seem relatively useless, but it allows a variable to be declared in the conditional that isn't actually set until the loop body: |
|||
<syntaxhighlight lang="raku" line>repeat until my $answer ~~ 42 { |
|||
$answer = prompt "Gimme an answer: "; |
|||
}</syntaxhighlight> |
|||
This would require a prior declaration (and two extra semicolons, horrors) |
|||
if written in the non-inverted form with the conditional at the bottom: |
|||
<syntaxhighlight lang="raku" line>my $answer; |
|||
repeat { |
|||
$answer = prompt "Gimme an answer: "; |
|||
} until $answer ~~ 42;</syntaxhighlight> |
|||
You can't just put the <tt>my</tt> on the <tt>$answer</tt> in the block because the conditional is outside the scope of the block, and would not see the declaration. |
|||
=={{header|REXX}}== |
|||
The closest thing that the REXX language has as far as inverted syntax |
|||
would be the use of the special case of the '''signal''' instruction: |
|||
<pre> |
|||
SIGNAL {ON|OFF} someCondition {name} |
|||
</pre> |
|||
<syntaxhighlight lang="rexx">/*REXX program demonstrates a use of a special case of inverted syntax (via SIGNAL ON).*/ |
|||
signal on syntax |
|||
a=7 |
|||
zz=444 / (7-a) |
|||
return zz |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
syntax: say '***error*** program is attempting to do division by zero,' |
|||
say 'the REXX statement number is: ' sigL " and the REXX source is:" |
|||
say sourceLine(sigL) |
|||
exit 13</syntaxhighlight> |
|||
'''output''' |
|||
<pre> |
|||
***error*** program is attempting to do division by zero, |
|||
the REXX statement number is: 4 and the REXX source is: |
|||
zz=444 / (7-a) |
|||
</pre> |
|||
=={{header|RPL}}== |
|||
Assigning values to variables using <code>→</code> or <code>STO</code> commands presents an inverted syntax in RPL. It's also possible to invert syntax for conditional expressions, by pushing the action in the stack as a lambda expression before doing the test, but this isn't idiomatic. |
|||
≪ 1 → raining <span style="color:grey">@ Set raining to true</span> |
|||
≪ ≪ NEEDUMBRELLA ≫ |
|||
'''IF''' raining '''THEN''' EVAL '''ELSE''' DROP '''END''' <span style="color:grey">@ Execute above action if true, else pop it from stack</span> |
|||
≫ ≫ '<span style="color:blue">TASK</span>' STO <span style="color:grey">@ Store above program in TASK variable</span> |
|||
=={{header|Ruby}}== |
|||
Ruby takes, from Perl, the idea of a ''statement modifier''. |
|||
This looks like <code>''statement'' if ''condition''</code> and appends a condition to some statement. |
|||
This example shows how to invert <code>if</code>, <code>unless</code>, <code>while</code> and <code>until</code>. |
|||
These always check the condition ''before'' running the statement. |
|||
<syntaxhighlight lang="ruby"># Raise ArgumentError if n is negative. |
|||
if n < 0 then raise ArgumentError, "negative n" end |
|||
raise ArgumentError, "negative n" if n < 0 |
|||
# Exit 1 unless we can call Process.fork. |
|||
unless Process.respond_to? :fork then exit 1 end |
|||
exit 1 unless Process.respond_to? :fork |
|||
# Empty an array, printing each element. |
|||
while ary.length > 0 do puts ary.shift end |
|||
puts ary.shift while ary.length > 0 |
|||
# Another way to empty an array, printing each element. |
|||
until ary.empty? do puts ary.shift end |
|||
puts ary.shift until ary.empty?</syntaxhighlight> |
|||
One can also modify a compound statement, as in <code>(warn "cannot fork"; exit 1) unless Process.respond_to? :fork</code>. |
|||
''Beware:'' The forms <code>begin ... end while ...</code> and <code>begin ... end until ...</code> have a different meaning to Ruby. |
|||
These forms check the condition ''after'' each iteration, so they run the loop at least once. [[Loops/Do-while#Ruby]] has more information. |
|||
=={{header|Scala}}== |
|||
<syntaxhighlight lang="scala">object Main extends App { |
|||
val raining = true |
|||
val needUmbrella = raining |
|||
println(s"Do I need an umbrella? ${if (needUmbrella) "Yes" else "No"}") |
|||
}</syntaxhighlight> |
|||
=={{header|Sidef}}== |
|||
<syntaxhighlight lang="ruby"># Inverted syntax with assignment |
|||
var raining = true; |
|||
[false]»(\var needumbrella); |
|||
# Inverted syntax with conditional expressions |
|||
if (raining==true) {needumbrella=true}; |
|||
{needumbrella=true} -> if (raining==true); |
|||
(needumbrella=true) if (raining==true);</syntaxhighlight> |
|||
=={{header|Swift}}== |
|||
Inverted syntax can be done with custom operators |
|||
<syntaxhighlight lang="swift">infix operator ~= {} |
|||
infix operator ! {} |
|||
func ~=(lhs:Int, inout rhs:Int) { |
|||
rhs = lhs |
|||
} |
|||
func !(lhs:(() -> Void), rhs:Bool) { |
|||
if (rhs) { |
|||
lhs() |
|||
} |
|||
} |
|||
// Traditional assignment |
|||
var a = 0 |
|||
// Inverted using a custom operator |
|||
20 ~= a |
|||
let raining = true |
|||
let tornado = true |
|||
var needUmbrella = false |
|||
var stayInside = false |
|||
// Traditional conditional expression |
|||
if raining {needUmbrella = true} |
|||
// Inverted using a custom operator |
|||
_ = {stayInside = true} ! tornado</syntaxhighlight> |
|||
=={{header|Tcl}}== |
|||
Copied verbatim from do.tcl, a part of tcllib's control package. |
|||
<syntaxhighlight lang="tcl"> |
|||
# do.tcl -- |
|||
# |
|||
# Tcl implementation of a "do ... while|until" loop. |
|||
# |
|||
# Originally written for the "Texas Tcl Shootout" programming contest |
|||
# at the 2000 Tcl Conference in Austin/Texas. |
|||
# |
|||
# Copyright (c) 2001 by Reinhard Max <Reinhard.Max@gmx.de> |
|||
# |
|||
# See the file "license.terms" for information on usage and redistribution |
|||
# of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
|||
# |
|||
# RCS: @(#) $Id: do.tcl,v 1.6 2004/01/15 06:36:12 andreas_kupries Exp $ |
|||
# |
|||
namespace eval ::control { |
|||
proc do {body args} { |
|||
# |
|||
# Implements a "do body while|until test" loop |
|||
# |
|||
# It is almost as fast as builtin "while" command for loops with |
|||
# more than just a few iterations. |
|||
# |
|||
set len [llength $args] |
|||
if {$len !=2 && $len != 0} { |
|||
set proc [namespace current]::[lindex [info level 0] 0] |
|||
return -code error "wrong # args: should be \"$proc body\" or \"$proc body \[until|while\] test\"" |
|||
} |
|||
set test 0 |
|||
foreach {whileOrUntil test} $args { |
|||
switch -exact -- $whileOrUntil { |
|||
"while" {} |
|||
"until" { set test !($test) } |
|||
default { |
|||
return -code error \ |
|||
"bad option \"$whileOrUntil\": must be until, or while" |
|||
} |
|||
} |
|||
break |
|||
} |
|||
# the first invocation of the body |
|||
set code [catch { uplevel 1 $body } result] |
|||
# decide what to do upon the return code: |
|||
# |
|||
# 0 - the body executed successfully |
|||
# 1 - the body raised an error |
|||
# 2 - the body invoked [return] |
|||
# 3 - the body invoked [break] |
|||
# 4 - the body invoked [continue] |
|||
# everything else - return and pass on the results |
|||
# |
|||
switch -exact -- $code { |
|||
0 {} |
|||
1 { |
|||
return -errorinfo [ErrorInfoAsCaller uplevel do] \ |
|||
-errorcode $::errorCode -code error $result |
|||
} |
|||
3 { |
|||
# FRINK: nocheck |
|||
return |
|||
} |
|||
4 {} |
|||
default { |
|||
return -code $code $result |
|||
} |
|||
} |
|||
# the rest of the loop |
|||
set code [catch {uplevel 1 [list while $test $body]} result] |
|||
if {$code == 1} { |
|||
return -errorinfo [ErrorInfoAsCaller while do] \ |
|||
-errorcode $::errorCode -code error $result |
|||
} |
|||
return -code $code $result |
|||
} |
|||
} |
|||
#usage: |
|||
package require control |
|||
control::do {set i 0; puts "hello world"; incr i} until {$i > 0} |
|||
</syntaxhighlight> |
|||
A more radical and probably ill-advised approach is to use the above |
|||
and modify the default tcl unknown procedure along these lines: |
|||
<syntaxhighlight lang="tcl"> |
|||
rename unknown __unknown |
|||
proc unknown {args} { |
|||
if {3 == [llength $args]} { |
|||
package require control |
|||
return [control::do {*}$args] |
|||
} else { |
|||
return [__unknown {*}$args] |
|||
} |
|||
} |
|||
#usage |
|||
% {set i 0; puts "hello world"; incr i} until {$i > 0} |
|||
hello world |
|||
</syntaxhighlight> |
|||
=={{header|TI-83 BASIC}}== |
|||
Assignment uses inverted syntax. |
|||
<syntaxhighlight lang="ti83b">536→N</syntaxhighlight> |
|||
=={{header|Wortel}}== |
|||
The <code>~</code> operator reverse the arguments of the next operator. |
|||
<syntaxhighlight lang="wortel">; a = expr |
|||
:a expr |
|||
; expr = a |
|||
~:expr a |
|||
; if cond expr |
|||
@if cond expr |
|||
; if expr cond |
|||
~@if expr cond</syntaxhighlight> |
|||
=={{header|Wren}}== |
|||
Follows the lines of the Go example which is probably the nearest Wren can get to inverted syntax also. |
|||
Again, simulating inverted syntax with assignment is not possible. |
|||
<syntaxhighlight lang="wren">class IBool { |
|||
construct new(b) { |
|||
if (!(b is Bool)) Fiber.abort("B must be a boolean") |
|||
_b = b |
|||
} |
|||
iff(cond) { cond ? _b : !_b } |
|||
} |
|||
var itrue = IBool.new(true) |
|||
var needUmbrella |
|||
var raining = true |
|||
// normal syntax |
|||
if (raining) needUmbrella = true |
|||
System.print("Is it raining? %(raining). Do I need an umbrella? %(needUmbrella)") |
|||
// inverted syntax |
|||
raining = false |
|||
needUmbrella = itrue.iff(raining) |
|||
System.print("Is it raining? %(raining). Do I need an umbrella? %(needUmbrella)")</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Is it raining? true. Do I need an umbrella? true |
|||
Is it raining? false. Do I need an umbrella? false |
|||
</pre> |
|||
=={{header|Z80 Assembly}}== |
|||
Syntax on the Z80 is very rigid; macros notwithstanding there is very little support for inverted syntax. However, since the CPU is little-endian, you can store 16-bit data as a word or 2 bytes: |
|||
<syntaxhighlight lang="z80">byte &EF,&BE |
|||
word &BEEF</syntaxhighlight> |
|||
Both of the above are equivalent. |
|||
=={{header|zkl}}== |
|||
zkl is a OO language so the preferred style is object.method().method()... |
|||
When a computation needs to be done first, the compose op (colon) can be used maintain the "noun/verb/verb" flow: f() : ... |
|||
It is also useful to "unwind" computations so they are easier to read |
|||
but not require any temp vars. |
|||
<syntaxhighlight lang="zkl">if (raining==True) needumbrella:=True; |
|||
(raining==True) : if (_) needumbrella:=True;</syntaxhighlight> |
|||
<syntaxhighlight lang="zkl">a := 6 |
|||
6 : a:=_</syntaxhighlight> |
|||
<syntaxhighlight lang="zkl">key.sort(fcn(kv,kv2){kv[0] < kv2[0]}) : listUnzip(_) : |
|||
D.SD((_).xplode()) : return(_);</syntaxhighlight> |
|||
{{omit from|AutoHotkey|the traditional if, expression if, and ternary op do not provide for this.}} |
|||
[[Category:Inverted syntax]] |
|||
{{omit from|AWK|Awk puts the condition before the action (except for the do-while loop, which puts the condition after the action). There is no way to invert the order.}} |
|||
{{omit from|BBC BASIC}} |
|||
{{omit from|bc|bc puts the condition before the action. There is no way to invert the order.}} |
|||
{{omit from|Brlcad}} |
|||
{{omit from|C sharp}} |
|||
{{omit from|Delphi}} |
|||
{{omit from|DWScript}} |
|||
{{omit from|F Sharp}} |
|||
{{omit from|Free Pascal}} |
|||
{{omit from|GAP}} |
|||
{{omit from|GUISS}} |
|||
{{omit from|Lotus 123 Macro Scripting}} |
|||
{{omit from|Nemerle}} |
|||
{{omit from|NetRexx}} |
|||
{{omit from|Pascal}} |
|||
{{omit from|UNIX Shell}} |
|||
{{omit from|ZX Spectrum Basic|The language syntax does not really allow this.}} |
Latest revision as of 14:33, 17 March 2024
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
Inverted syntax with conditional expressions
In traditional syntax conditional expressions are usually shown before the action within a statement or code block:
IF raining=true THEN needumbrella=true
In inverted syntax, the action is listed before the conditional expression in the statement or code block:
needumbrella=true IF raining=true
Inverted syntax with assignment
In traditional syntax, assignments are usually expressed with the variable appearing before the expression:
a = 6
In inverted syntax, the expression appears before the variable:
6 = a
Task
The task is to demonstrate support for inverted syntax forms within the language by showing both the traditional and inverted forms.
6502 Assembly
Branching
Conditional branches are limited in the range they can branch; all branch statements cannot be more than 127 or -128 bytes away from their destination.
The below example will result in an assemble time error. The intended action is that the X variable is decremented, and execution returns to the top of the loop. However, the branch is simply too far away.
loop_MySubroutine:
; more than 127 bytes of code
dex
bne loop_MySubroutine ;assembler will display an error message that the branch is too far away.
; rest of program
The easiest way to overcome this limitation is to invert the branch condition and place a JMP
back to the loop under it.
An unconditional JMP
moves the program counter to the specified location, no matter where that is.
loop_mySubroutine:
; more than 127 bytes of code
dex
beq continue
JMP loop_mySubroutine
continue:
; rest of program
Now, what happens is that the opposite condition is checked. If X = 0, execution branches 3 bytes forward to "continue." Otherwise, the statement underneath the branch is executed, which is a jump back to the top.
16-Bit Data
Being a little-endian CPU, the "low byte" (rightmost 2 digits) of a 16-bit (4-digit) hexadecimal number is stored before the "high byte" (leftmost 2 digits). This is difficult for a human to read but easier for the CPU. The assembler allows the programmer to use a dw
or word
directive to define 16-bit data values in a manner easier for a person to read. The assembler swaps the order of the bytes automatically when assembling the source code.
word $BEEF
byte $EF,$BE
A hexdump of these bytes would display them the same, i.e.:
EF BE EF BE
Ada
The only place where syntax is kind of inverted is exit when
to exit loops:
Foo := 1;
loop
exit when Foo = 10;
Foo := Foo + 1;
end loop;
ALGOL 68
# Inverted assignment #
# Assignment in Algol 68 is via ":=" which is automaically provided for all modes (types) #
# However we could define e.g. "=:" as an inverted assignment operator but we would need to #
# define a separate operator for each mode, e.g. for integers and strings: #
PRIO =: = 1;
OP =: = ( INT a, REF INT b )REF INT: b := a;
OP =: = ( STRING a, REF STRING b )REF STRING: b := a;
OP =: = ( CHAR a, REF STRING b )REF STRING: b := a;
INT a, b; STRING s;
1 =: a;
a + 1 =: b;
"?" =: s;
print( ( a, b, s, newline ) );
# There is one standard inverted assignment operator: +=: or PLUSTO which prepends a string #
# to another: #
"bc" =: s;
"b" +=: s;
print( ( s, newline ) );
# Inverted Conditional Expressions #
# We could define an operator called WHEN perhaps, that would execute its left operand if #
# the right operand was TRUE. However the left operand would need to be a PROC VOID so the #
# syntax would not be as convientent as the standard IF-THEN-FI construct. E.g.: #
PRIO WHEN = 1;
OP WHEN = ( PROC VOID code, BOOL test )VOID: IF test THEN code FI;
( VOID: print( ( "NO", newline ) ) ) WHEN a = b; # the anonymous PROC VOID is not called #
( VOID: print( ( "yes", newline ) ) ) WHEN a /= b # the anonymous PROC VOID is called #
- Output:
+1 +2? bbc yes
ARM Assembly
Typically, instructions with a destination register and a source register will have the leftmost register be the destination and the registers to the right be the source.
MOV R0,R3 ;copy R3 to R0
ADD R2,R1,R5 ;add R1 to R5 and store the result in R2.
However there is one exception: the STR
command. Its source is on the left and its destination is on the right. This inverted syntax is not optional.
STR r0,[r4] ;store the contents of R0 into the memory location specified by R4.
This was most likely done for symmetry with the "push/pop" commands:
STMFD sp!,{r0-r12,lr} ;push r0 thru r12 and the link register
LDMFD sp!,{r0-r12,pc} ;pop r0 thru r12, and the value that was in the link register is popped into the program counter.
Arturo
In this case, we can define a reversed if-statement function (taking the block first, then the condition) and then "alias" a new symbol to it, as an infix operator (so that the block actually comes first, in terms of syntax:
ifStatement: function [block, condition][
if condition -> do block
]
alias.infix {??} 'ifStatement
do [
variable: true
[print "Variable is true!"] ?? variable
]
- Output:
Variable is true!
Bracmat
The match operator :
can play the role of an inverted assignment operator =
. The following two definitions of a function double
are equivalent.
double=.!arg+!arg;
(=.!arg+!arg):(=?double); { inverted assignment syntax, same result as above. }
Bracmat evaluates all left hand sides of all binary operators. How right hand sides are treated depends on the operator. The =
operator does not evaluate its right hand side at all. The right hand side of the :
operator is evaluated by a dedicated match evaluator, which for example sees the expression ?double
as a variable to be bound to some part of the left hand side of the :
operator.
The following two assignments are not equivalent:
foo=3+7 { assigns 3+7 to foo }
3+7:?foo { assigns 10 to foo }
C
C doesn't have a way to do this cleanly. You need to drop some code before the statements you want to invert. I'll use CPP to make it look as close as I think you can make it. -- ksb, Jan 2013
The original would be "if (foo()) a = 4;" Here is the inverted if logic using "otherwise ... given () ;"
#include <stdio.h>
#include <stdlib.h>
#define otherwise do { register int _o = 2; do { switch (_o) { case 1:
#define given(Mc) ;case 0: break; case 2: _o = !!(Mc); continue; } break; } while (1); } while (0)
int foo() { return 1; }
main()
{
int a = 0;
otherwise a = 4 given (foo());
printf("%d\n", a);
exit(0);
}
Which actually makes the main program look like:
main()
{
int a = 0;
do {
register int _o = 2;
do {
switch (_o) {
case 1:
a = 4;
case 0:
break;
case 2:
_o = !!(foo());
continue;
} break;
} while (1);
} while (0);
printf("%d\n", a);
exit(0);
}
To make lint happy you need a /*FALLTHROUGH*/ before the case 0 (in the macro).
C++
Though rarely, if ever, used in practice, user-defined class types can have inverted syntax with assignment.
class invertedAssign {
int data;
public:
invertedAssign(int data):data(data){}
int getData(){return data;}
void operator=(invertedAssign& other) const {
other.data = this->data;
}
};
#include <iostream>
int main(){
invertedAssign a = 0;
invertedAssign b = 42;
std::cout << a.getData() << ' ' << b.getData() << '\n';
b = a;
std::cout << a.getData() << ' ' << b.getData() << '\n';
}
It doesn't work if the left operand is not of the type invertedAssign.
Clojure
The "thread last" macro permits inversion of syntax in virtually all contexts. Any form for which the construction of a new list from consecutive elements doesn't change the semantics may be turned "inside-out"; this is to the exclusion of those containing function definitions and little else.
; normal
(if (= 1 1)
(print "Math works."))
; inverted
(->> (print "Math still works.")
(if (= 1 1)))
; a la Haskell
(->> (print a " is " b)
(let [a 'homoiconicity
b 'awesome]))
Expanding the macro reveals the nature of the aforementioned limitation.
((fn [x] (* x x) 5) ; Define a lambda and call it with 5.
(macroexpand-1 '(->> 5 (fn [x] (* x x))))
(fn [x] (* x x) 5) ; Define a lambda that returns 5 regardless.
The "thread first" macro (colloquially, the Thrush) provides a similar facility, wherein each expression becomes the first argument to the next.
(= (mod (inc 42) 7)
(-> 42 inc (mod 7)))
CoffeeScript
CoffeeScript allows loop constructs and conditionals to be written in a suffix manner. Loop constructs evaluate to an array containing the result of each iteration; conditionals evaluates either the true-case expression or the false-case one.
alert "hello" if true
alert "hello again" unless false # the same as the above; unless is a negated if.
idx = 0
arr = (++idx while idx < 10) # arr is [1,2,3,4,5,6,7,8,9,10]
idx = 0
arr = (++idx until idx is 10) # same as above; until is an inverted while.
Common Lisp
Lisp has a PROGN macro for evaluating a bunch of forms, such that the value(s) of the last one is yielded as the result of the PROGN. We can create a reversed analog of PROGN, inside which, we must write the syntax backwards: arguments first, then the operator. Furthermore, this rule is recursively applied to expressions.
Note: unfortunately this is completely naive. To do this 100% right, we need a code walker, which is more complicated. However, code walkers are used in practice for hairy language transformation jobs, just not commonly so in daily Lisp programming. A code walker would let us imlement a more smarter version which would apply the transformation to forms which are evaluated, and not things like literal data. As it is, our macro also transforms literal data, making it impossible, for instance, to use the quote shorthand 'FORM. This stands for (QUOTE FORM) and of course, the macro will treat it as reversed syntax, transforming it to (FORM QUOTE). We could hack in a special case which recognized QUOTE, but then we do not know whether or not (QUOTE FORM) is in a context where it is being evaluated. That is why we need the code walker. It's best to use someone's well-tested, portable code-walker, since they are not trivial to write, and they have some implementation-specific parts (such as recognition of compiler-specific forms that come out of system macros or perhaps out of user-written nonportable code).
(eval-when (:compile-toplevel :load-toplevel :execute)
(defun unrev-syntax (form)
(cond
((atom form) form)
((null (cddr form)) form)
(t (destructuring-bind (oper &rest args) (reverse form)
`(,oper ,@(mapcar #'unrev-syntax args)))))))
(defmacro rprogn (&body forms)
`(progn ,@(mapcar #'unrev-syntax forms)))
Interactive test run:
$ clisp -q -i reverse.lisp ;; Loading file reverse.lisp ... ;; Loaded file reverse.lisp [1]> (rprogn ((1 2 +) (3 4 +) *)) 21 [2]> (rprogn (("not greater" print) ("greater" print) (1 2 >) if)) "greater" "greater" [3]> (macroexpand '(rprogn (("not greater" print) ("greater" print) (1 2 >) if))) (PROGN (IF (> 2 1) (PRINT "greater") (PRINT "not greater"))) ; T
Now here is a slightly more complicated version which more closely conforms to the idea given in this task. The operator is assumed to be the second-last element of a form. The last element of the form is the first argument, and the forms prior to the operator are the remaining arguments (in reverse order). These rules are recursively applied to each of the arguments, but not to the operator. A two element form is assumed to be (argument operator), and is rewritten to (operator argument*) where argument* is the result of applying the unreversal to the argument:
(eval-when (:compile-toplevel :load-toplevel :execute)
(defun unrev-syntax (form)
(cond
((atom form) form) ;; atom: leave alone
((null (cdr form)) form) ;; one-element form: leave alone
((null (cddr form)) ;; two-element form: swap
(destructuring-bind (arg oper) form
`(,oper ,(unrev-syntax arg))))
(t ;; two or more args: swap last two, add others in reverse
(destructuring-bind (arg1 oper &rest args) (reverse form)
`(,oper ,(unrev-syntax arg1) ,@(mapcar #'unrev-syntax args)))))))
(defmacro rprogn (&body forms)
`(progn ,@(mapcar #'unrev-syntax forms)))
[1]> (rprogn ((1 + 2) * (3 + 4))) 21 [2]> (rprogn (("not equal" print) ("equal" print) if (1 = 2))) "not equal" "not equal" [3]> (rprogn (("not equal" print) ("equal" print) if (1 = 1))) "equal" "equal" [4]> (macroexpand '(rprogn (("not equal" print) ("equal" print) if (1 = 1)))) (PROGN (IF (= 1 1) (PRINT "equal") (PRINT "not equal"))) ; T [5]> (macroexpand '(rprogn ((1 + 2) * (3 + 4)))) (PROGN (* (+ 4 3) (+ 2 1))) ; T
D
D enables a function to be called as if it were a method of its first argument. This feature often leads to natural syntax and readable, left-to-right expressions:
#!/usr/bin/rdmd
import std.algorithm;
void main() {
assert("Hello, World".length == 12);
assert("Cleanliness".startsWith("Clean"));
auto r = [1, 4, 2, 8, 5, 7]
.filter!(n => n > 2)
.map!(n => n * 2);
assert(r.equal([8, 16, 10, 14]));
}
EchoLisp
;; use reader macros to transform (a OP b) into (OP b a)
(lib 'match)
(define-macro invert-= (a <- b) (set! b a))
(define-macro invert-IF (a 'IF b) (when b a))
(define raining #f)
(#t <- raining)
raining
→ #t
('umbrella-need IF raining)
→ umbrella-need
(#f <- raining)
('umbrella-need IF raining)
→ #f
;; debug mode
(debug 3)
('umbrella-need IF raining)
💡 [0] invert-IF → ('umbrella-need IF raining)
compiled :: (#when raining 'umbrella-need)
Factor
Since code is data in Factor, we can simply reverse it, transforming postfix into "prefix."
1 1 + ! 2
[ + 1 1 ] reverse call ! 2
{ 1 2 3 4 5 } [ sq ] map ! { 1 4 9 16 25 }
[ map [ sq ] { 1 2 3 4 5 } ] reverse call ! { 1 4 9 16 25 }
In fact, using a Lisp-style macro, we can perform this transformation at parse time:
MACRO: pre ( quot -- quot ) reverse ;
[ + 2 2 ] pre ! 4
Of course, this isn't true prefix because +
retains its arity of 2:
[ + 3 + 2 2 ] pre ! 7
We can define a more accurate prefix macro for addition and subtraction in terms of reduce
:
MACRO: pre ( quot -- quot ) 1 cut swap [ 0 ] dip reduce 1quotation ;
[ + 1 2 3 4 5 ] pre ! 15
Additionally, using parsing words, we can add any syntax we like. The infix
vocabulary is an example of this:
USE: infix
[infix
5*(1+1) ! 10
infix]
Fortran
Leaving aside those who think that Fortran is inherently backward, assignment in Fortran is firmly right-to-left in the form variable = expression
where the expression is computed in accordance with the precedence rules and the resulting value is assigned to the variable.
However, assignment-style constructions appear inside the INQUIRE statement as in
INQUIRE(FILE = FILENAME(1:L), EXIST = MAYBE, ERR = 666, IOSTAT = RESULT)
Here, a logical variable MAYBE is to receive the value of whether or not the disc file named in FILENAME(1:L) exists, and integer variable RESULT contains an error code, zero if all went well - the file name may not be correctly formed, for example. Thus, FILE is receiving a value right-to-left on entry to the statement, while MAYBE and RESULT receive values left-to-right on exit from the statement. Despite appearances, ERR = 666
is not an assignment statement; 666 is not an integer, it is a statement label to which execution will jump should an error arise. Similar arrangements apply for the file OPEN and CLOSE statements.
There is no deviationism with the workings of IF-statements.
FreeBASIC
FreeBASIC has nothing like this built into the language. The nearest we can get is to define macros which reverse the order of the arguments:
' FB 1.05.0 Win64
#Define ThenIf(a, b) If b Then a
#Define InvertAssign(a, b) b = a
Dim As Boolean needUmbrella = False, raining = True
ThenIf(needUmbrella = True, raining = True)
Print "needUmbrella = "; needUmbrella
Dim As Integer b = 0, a = 3
InvertAssign(a, b)
Print "b is"; b
Sleep
- Output:
needUmbrella = true b is 3
Fōrmulæ
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.
Programs in Fōrmulæ are created/edited online in its website.
In this page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.
Inverted syntax with conditional expressions
The following is how is visualized the common IF expression:
The following is the visualization of the inverted IF expression. Notice that they are different expressions, in order that they can be visualized in different form, but they reduce the same way.
Inverted syntax with assignment
The assignment expression does not have an inverted form.
Go
The closest Go can get to inverted syntax for conditionals is to define a new type ('ibool' say) based on the built-in 'bool' type and then define a method ('iif' say) on the new type which takes the place of the traditional 'if'.
Simulating inverted syntax with assignment is not possible.
package main
import "fmt"
type ibool bool
const itrue ibool = true
func (ib ibool) iif(cond bool) bool {
if cond {
return bool(ib)
}
return bool(!ib)
}
func main() {
var needUmbrella bool
raining := true
// normal syntax
if raining {
needUmbrella = true
}
fmt.Printf("Is it raining? %t. Do I need an umbrella? %t\n", raining, needUmbrella)
// inverted syntax
raining = false
needUmbrella = itrue.iif(raining)
fmt.Printf("Is it raining? %t. Do I need an umbrella? %t\n", raining, needUmbrella)
}
- Output:
Is it raining? true. Do I need an umbrella? true Is it raining? false. Do I need an umbrella? false
Haskell
Because Haskell is an expression-based pure functional language, this cannot be defined in the general case, because not every expression has a type with a null-like default value that can be inferred.
However, for the common case where you want to perform a certain action only when some condition holds, you can define a simple binary operator:
when :: Monad m => m () -> Bool -> m ()
action `when` condition = if condition then action else return ()
Example usage:
Prelude> putStrLn "It's true." `when` False Prelude> putStrLn "It's true." `when` True It's true. Prelude>
Haskell has a feature that can be considered "inverted" syntax (although it is not one of the types listed in the description of the task): The definition of local variables to be used in a function can be placed in a where
clause that comes after the function body:
func a b x = (x + y) / y
where y = a * b
This is in contrast to let
expressions, where the definition of local variables comes before the scope that uses them:
func a b x =
let y = a * b in
(x + y) / y
The standard Data.Bool module defines a bool function.
bool x y p evaluates to x when p is False, and evaluates to y when p is True.
import Data.Bool (bool)
main :: IO ()
main = do
let raining = False
putStrLn $ bool "No need" "UMBRELLA !" raining
putStrLn $ flip bool "No need" "UMBRELLA !" raining
putStrLn "\n--------\n"
mapM_ putStrLn $
[bool, flip bool]
<*> ["No need"]
<*> ["UMBRELLA !"]
<*> [raining, not raining]
- Output:
No need UMBRELLA ! -------- No need UMBRELLA ! UMBRELLA ! No need
Icon and Unicon
Icon and Unicon can use expression conjunctions that select different sub-expression results to create this effect.
J
J tries to minimize syntax and control structures. However, they are present.
For control structures, "traditional conditional structures" are traditional (control structures implemented using keywords such as if.
are not inverted). But J offers some alternatives which are inverted (operations such as ^:
) or both (operations such as *
(multiplication) can be used as inverted conditional structures or as traditional conditional structures, depending on whether you place the boolean test on the left or the right side). See Conditional_Structures/J for some examples.
Note also that simple, regular iteration without control structures is fundamental to the language (and turns data selection operations, including indexing, into conditional structures). But no special syntax is present for these cases so it can be neither traditional nor inverted.
Java
The closest Java comes to placing an action before a condition is with
do ... while(condition);
jq
jq's syntax for associating a value with a variable is "inverted": the expression for associating a value, v, with a variable, $x, is:
v as $x
Note, however, that there is limited support for the conventional "target = value" syntax in the context of JSON objects and arrays, but the semantics is purely functional.
For example, if o is {"a": 1}, then the expression:
o["a"] = 2
# or equivalently: o.a = 2
emits another object equal to {"a": 2}.
Julia
Can be easily implemented as a macro:
macro inv(expr, cond)
cond isa Expr && cond.head == :if || throw(ArgumentError("$cond is not an if expression"))
cond.args[2] = expr
return cond
end
@inv println("Wow! Lucky Guess!") if true else println("Not!") end
Koka
Using the byref function and infix operators we can get both inverted assignments as well as inverted conditionals in Koka! However, the branch to the conditional is evaluated prior to the condition unless you explicitly delay it or accept a closure.
fun (=:)(c: c, v: local-var<h, c>): <local<h>> ()
v := c
fun (?)(c: c, b: bool): e maybe<c>
if b then Just(c) else Nothing
fun main()
var x := 4
6 =: std/core/types/byref(x)
x.println
val res = "Yes" ? True
match res
Just(a) -> println(a)
Nothing -> throw("Nothing")
- Output:
6 Yes
Kotlin
Kotlin can get close to an inverted 'if' syntax by defining an infix function - 'iif' say. However, there doesn't appear to be a way to mimic inverted assignment.
// version 1.0.6
infix fun Boolean.iif(cond: Boolean) = if (cond) this else !this
fun main(args: Array<String>) {
val raining = true
val needUmbrella = true iif (raining)
println("Do I need an umbrella? ${if(needUmbrella) "Yes" else "No"}")
}
- Output:
Do I need an umbrella? Yes
Latitude
Latitude, by default, does not support inverted conditionals, as its two primary means of conditional branching both involve the condition first.
local 'raining = True.
local 'needUmbrella = False.
if (raining) then {
needUmbrella = True.
} else {}.
{ raining. } ifTrue {
needUmbrella = True.
}.
However, such constructs can easily be added to the language.
#'Method when := {
localize.
if ($1) then {
this.
} else { }.
}.
#'Method unless := {
#'self when ($1 not).
}.
;; Example usage
{ needUmbrella = True. } when (raining).
{ needUmbrella = True. } unless (raining not).
Likewise, inverted assignment syntax is not supported natively, but it can be approximated in-language, using a definition similar to that of the built-in local=
.
global let= := { self slot ($2) = #'$1. }.
local 'a = 6.
println: a. ;; 6
let 6 = 'b.
println: b. ;; 6
Lua
In general, Lua does not support any truly inverted syntax, though there are some metamethod techniques and taking advantage of syntactic sugar that perhaps at least give the illusion that syntax has been inverted. Here, calling a library method passing a table, versus the table itself calling as if its own method, equivalently:
a = {1,3,5,4,2} -- a "plain" table
table.sort(a) -- library method passing a as param
print(table.concat(a)) -- and again --> "12345"
b = {1,3,5,4,2} -- a "plain" table, so far..
setmetatable(b, {__index=table}) -- ..but now "meta-decorated"
b:sort() -- syntax sugar passes b as "self"
print(b:concat()) -- and again --> "12345"
M2000 Interpreter
There is no way to have inverted syntax for conditionals, except for using lambda functions. Three more things we can do. One to invert the way we call a module, passing statements before calling the module. The Second by using Let we make a Push and then a Read, so first evaluated the right expression and then the left. Here we change a global variable in the right expression and we change the index of array where we set the returned value from function. The third one is more complicated. We make a callback function which act as code of a module, with same scope, and use a module to check condition before we call the callback function
expr=lambda ->{
Print "ok"
}
ifrev=lambda (dothis, cond) ->{
if cond then call dothis()
}
a=1
call ifrev(expr, a=1)
\\ on module call
Module Subtract (a, b) {
Push a-b
}
Module PrintTop {
Print Number
}
Subtract 10, 3 : PrintTop
\\ pushing before calling in reverse order
Push 3, 10 : Subtract : PrintTop
\\ Before call PrintTop any parameter send to stack
\\ So this works ok
PrintTop 1000
\\ on assignment
Dim A(5)=1
Global n=2
Function AddOne (x) {
n++
=x
}
\\ Execution of left expression, then right expression
A(n)=AddOne(5)
Print A(n-1)=5, n=3
\\ Execution of right expression, then left expression
Let A(n)=AddOne(15)
Print A(n)=15, n=4
\\ This statement..
Let X=1, Y=2
\\ executed like these
Push 2, 1 : Read X, Y
\\ This is the CallBack way
Module ExecCond {
Read &callback(), cond
if cond then call callback()
}
x=1
\\ this aa() is a function but when we call it after transforming from Lazy$()
\\ act as part of module so we see x, and alter it
Function aa {
x++
}
a=1
ExecCond Lazy$(&aa()), A=1
Print x=2
m4
We extend our language with a new macro, thenif
,
to invert the arguments to the builtin macro, ifelse
.
define(`thenif', `ifelse($2, $3, `$1')')dnl
dnl
ifelse(eval(23 > 5), 1, 23 is greater than 5)
ifelse(eval(23 > 5), 0, math is broken)
thenif(23 is greater than 5, eval(23 > 5), 1)
thenif(math is broken, eval(23 > 5), 0)
This example outputs these four lines. Math was not broken, so two lines are empty.
23 is greater than 5 23 is greater than 5
Mathematica /Wolfram Language
Traditional form:
a = 4
->4
b = 5
->5
If[1<2,
Print["This was expected"]
]
->This was expected
Inversion of syntax:
Unprotect["="]; SetAttributes[Set2, HoldAll]; Set2[a_, b_] := Set[b, a] << Notation`; Notation[ParsedBoxWrapper[RowBox[{"x_", "=","y_"}]] \[DoubleLongLeftRightArrow] ParsedBoxWrapper[RowBox[{" ", RowBox[{"Set2", "[", RowBox[{"x_", ",", "y_"}], "]"}]}]]] 2 = c ->2 3 = d ->3 Unprotect["If"];SetAttributes[If2,HoldAll];If2[a_,b_]:=If[b,a] Notation[If[x_,y_] \[DoubleLongLeftRightArrow] If2[x_,y_]] If[Print["This was expected"], 1<2 ] ->This was expected
Mercury
For Mercury, order rarely matters. Just as programmers in most languages take care to order their function definitions or their method definitions for clarity and emphasis, while knowing that it's all the same to the compiler, Mercury programmers can do this also in the bodies of functions.
These two clauses are exactly the same:
:- pred progress(int::in, int::in, int::out, int::out) is det.
progress(Past, Future, At, Total) :-
At = Past + 1,
Total = Past + Future.
progress(Past, Future, At, Total) :-
Past + Future = Total,
Past + 1 = At.
Order doesn't matter even when a data dependency tells you (and Mercury's compiler) what the order of evaluation must be:
:- func example(int) = string.
example(N) = S :-
from_int(N) = S0,
pad_left(S0, '0', 3, S).
example(N) = S :-
pad_left(S0, '0', 3, S),
from_int(N) = S0.
Data dependencies are most obvious when state is threaded through a clause:
main(IO0, IO) :-
io.write_string("Hello, ", IO0, IO1),
io.write_string("world!\n", IO1, IO).
main(!IO) :-
io.write_string("Hello, ", !IO),
io.write_string("world!\n", !IO).
The io.write_string/2's in the first example could be written in either order and the result would be the same, as the "world!\n" can't be written until the "Hello, " provides the IO1. Order matters in the second example, however, as it uses state variables. The order is still enforced by a data dependency, so
main(!IO) :-
io.write_string(X, !IO), io.nl(!IO),
some_long_uninteresting_thing(X).
% this is the same:
main(!IO) :-
some_long_uninteresting_thing(X),
io.write_string(X, !IO), io.nl(!IO).
% but this is different!
main(!IO) :-
io.nl(!IO), io.write_string(X, !IO),
some_long_uninteresting_thing(X).
Metafont
Although there is an assignment operator, you can also define values of variables by equations, such as:
x=6;
7=y;
Therefore it can be done both ways.
Nim
Inverted syntax in Nim can be achieved through the use of templates as operators:
#--
# if statements
#--
template `?`(expression, condition) =
if condition:
expression
let raining = true
var needUmbrella: bool
# Normal syntax
if raining: needUmbrella = true
# Inverted syntax
(needUmbrella = true) ? (raining == true)
#--
# Assignments
#--
template `~=`(right, left) =
left = right
var a = 3
# Normal syntax
a = 6
# Inverted syntax
6 ~= a
Oforth
Oforth uses RPN so some forms a partially (or totally) inverted :
6 -> a : Push 6 on the stack and set the top of the stack as value of local variable a (top of the stack is consumed) 6 := a : Push 6 on the stack and set the top of the satck as value of attribute a (top of the stack is consumed). raining ifTrue: [ true ->needumbrella ]
OxygenBasic
Macros may have localised scope, so they can be safely deployed as HumptyDumpty words.
macro cond(a,c) {c then a}
macro store(b,a) {a=b}
sys a,c=10
if c>4 then a=4
'INVERTED SYNTAX FORMS:
cond a=40, if c>4
store 4,a
'COMBINED:
cond store(5,a), if c>4
PARI/GP
GP does not include a syntax-inverted if, but that can be defined using closures.
fi(f, condition)=if(condition,f());
if(raining, print("Umbrella needed"))
fi(->print("Umbrella needed"), raining)
PARI can also be used to implement it more directly in GP.
Perl
Perl already has that:
if ($guess == 6) { print "Wow! Lucky Guess!"; }; # Traditional syntax
print 'Wow! Lucky Guess!' if $guess == 6; # Inverted syntax (note missing braces and parens)
unless ($guess == 6) { print "Sorry, your guess was wrong!"; } # Traditional syntax
print 'Huh! You Guessed Wrong!' unless $guess == 6; # Inverted syntax
Inverted syntax can also be used with the ternary operator. However this may produce different results to the traditional syntax form because when inverted syntax is used, we are effectively making an assignment to a ternary expression. so in the following example code, instead of the assignment being made to variable a (as it is in the traditional syntax form), the inverted syntax form will cause assignment to be made to either b or c, depending on value of the ok variable:
# Note that the results obtained by the inverted syntax form
# may produce differing results from the traditional syntax form
$a = $ok ? $b : $c; # Traditional syntax
($ok ? $b : $c) = $a; # Inverted syntax
We can also emulate inverted syntax for scalar assignment by creating a function as follows:
sub assign { $_[1] = $_[0] }
$a = $b; # Traditional syntax
assign $b, $a; # Inverted syntax
Inverted list assignment is not possible because it prevents arrays from flattening.
Phix
original... the got still you've as long as ,itself compile/run to used be can This
if end (&"test.exw"[1]cl)system then >2(cl)length if (&"\n"(pgm)mung,"test.exw")write_file = {} write_file.e include ([$]cl)get_text = pgm string ()command_line = cl sequence function end ("\n",lines)join return for end (nup,rip,((([i]lines)split)reverse)join)substitute_all = [i]lines do (lines)length to 1=i for (("\r\n",(rip,pun,pgm)substitute_all)split)reverse=lines sequence (pgm string)mung function (true,"*",("*","",3,7," -<>{}@! ")join_by)split = rip constant (true,"*",("*","",1,7,"-,=][)(")join_by)split = nup constant (true,"*",("*","",1,7,"-,=[]()")join_by)split = pun constant js without demo\rosetta\inverted_syntax.exw --
I should note that "if length(cl)>2 then" gets away by the skin of its teeth and would break were it written "if length(cl) > 2 then".
... and here is the original, which can be used to first create and then re-run to compile/run the above, in fact destroying/restoring/recreating it in the latter process.
-- demo\rosetta\inverted_syntax.exw without js constant pun = split(join_by("()[]=,-",7,1,"","*"),"*",true) constant nup = split(join_by(")(][=,-",7,1,"","*"),"*",true) constant rip = split(join_by(" <>{}@!- ",7,3,"","*"),"*",true) function mung(string pgm) sequence lines=reverse(split(substitute_all(pgm,pun,rip),"\r\n")) for i=1 to length(lines) do lines[i] = substitute_all(join(reverse(split(lines[i]))),rip,nup) end for return join(lines,"\n") end function sequence cl = command_line() string pgm = get_text(cl[$]) include write_file.e {} = write_file("test.exw",mung(pgm)&"\n") if length(cl)>2 then system(cl[1]&"test.exw") end if
PicoLisp
We define a read macro for reverted syntax
(de rv Prg
(append (last Prg) (head -1 Prg)) )
Test:
(de needUmbrella (Raining) `(rv # Inverted syntax (on *NeedUmbrella) (println 'Need 'an 'umbrella) (when Raining) ) ) (de keepUmbrella (Raining) `(rv # Inverted syntax (on *KeepUmbrella) (println 'Still 'need 'an 'umbrella) (while Raining) ) )
- Output:
: (pp 'needUmbrella) (de needUmbrella (Raining) (when Raining # Traditional syntax (on *NeedUmbrella) (println 'Need 'an 'umbrella) ) ) : (pp 'keepUmbrella) (de keepUmbrella (Raining) (while Raining # Traditional syntax (on *KeepUmbrella) (println 'Still 'need 'an 'umbrella) ) )
PowerShell
The PowerShell syntax for an 'if' statement is very normal:
if ((Get-Date 5/27/2016).DayOfWeek -eq "Friday") {"Thank God it's Friday!"}
- Output:
Thank God it's Friday!
The order of the condition and expression can be easily reversed (with a slight change in syntax):
function Action ([scriptblock]$Expression, [Alias("if")][bool]$Test)
{
if ($Test) {&$Expression}
}
Set-Alias -Name say -Value Action
say {"Thank God it's Friday!"} -if (Get-Date 5/27/2016).DayOfWeek -eq "Friday"
- Output:
Thank God it's Friday!
Prolog
Prolog programs are made up of facts and rules. Facts are considered "true" if they are provable from the source code and "false" otherwise. The rules for proving new facts are described using "horn clauses" which are backwards "if" statements: the truth value of the second part becomes the truth value of the first part.
The facts themselves are usually expressed using "functors" involving parentheses, with the constant in front of the parentheses naming some property which applies to one or more items inside. As a result, they sometimes kind of look like backwards "is" statements.
% Dracula is a vampire.
% Also, you become a vampire if someone who is a vampire bites you.
vampire(dracula).
vampire(You) :- bites(Someone, You), vampire(Someone).
% Oh no! Dracula just bit Bob...
bites(dracula, bob).
- Output:
We load the source code into the interpreter and ask whether Alice and Bob are vampires...
?- vampire(alice). false. ?- vampire(bob). true .
Python
x = truevalue if condition else falsevalue
with open("file.txt") as f:
something(f)
Qi
(define set-needumbrella
Raining -> (set needumbrella true) where (= true Raining)
Raining -> (set needumbrella false) where (= false Raining))
(define set-needumbrella
Raining -> (if (= true Raining)
(set needumbrella true)
(set needumbrella false)))
Alternatives:
(define set-needumbrella
Raining -> (set needumbrella true) where Raining
Raining -> (set needumbrella false))
(define set-needumbrella
Raining -> (if Raining
(set needumbrella true)
(set needumbrella false)))
(define set-needumbrella
true -> (set needumbrella true)
false -> (set needumbrella false))
(define set-needumbrella
A -> (set needumbrella A))
Quackery
A Quackery program consists of numbers, words, and nests, collectively referred to as items. A nest is a sequence of zero or more items. Items are evaluated sequentially.
Some words can alter this sequential behaviour. if
for example, causes the item following it to be skipped if the number on the top of data stack (henceforth just "the stack") is zero (i.e. false.)
So, given that the word raining
returns a boolean (i.e. 0 or 1) indicating whether it is raining or not, and the word use-umbrella
deploys an umbrella, the usual syntax would be raining if use-umbrella
.
The word '
alters the sequential flow by causing the item following it to be placed on the stack rather than being evaluated. The word do
causes the item on the top of the stack to be evaluated. So we could define a new word, if.1
with
[ swap do iff do else drop ] is if.1
which would allow us to use the syntax ' raining ' use-umbrella if.1
. (iff
conditionally skips over two items, else
unconditionally skips over one item.)
'
is defined using the meta-control flow operator ]'[
thus: [ ]'[ ] is '
Meta-control flow operators grant their behaviour to the word that calls them. So if we wanted the syntax ' use-umbrella if.2 raining
we could define if.2
with
[ ]'[ do iff do else drop ] is if.2
Other syntaxes can be achieved by the judicious use of '
and ]'[
. To demonstrate just one that avoids the use of if ...
or iff ... else ...
entirely, one could define a word ifelse
as
[ not ]'[ nested ]'[ nested join swap peek do ] is ifelse</code>
This would have the syntax raining ifelse use-umbrella use-sunscreen
(for an appropriate definition of use-sunscreen
.)
Quackery does not have variables, so there is not exact equivalent to assignment, but it does have ancillary stacks which can be used in a variable-like manner. temp
is a predefined ancillary stack, and an item can be moved from the stack to it with the phrase temp put
. As with the previous examples, ]'[
can be used to vary the syntax.
R
This can be done with a simple function.
do.if <- function(expr, cond) if(cond) expr
Because R evaluates function arguments lazily, "expr" is never evaluated unless "cond" evaluates to true.
do.if(print("Wow! Lucky Guess!"), guess==6)
If you do not want to state "do.if" first, you can define an infix operator (any function whose name is bracketed in percent signs is treated as an infix operator), however custom infix operators have higher precedence than comparisons, so will usually require putting parentheses around the test.
`%if%` <- function(expr, cond) if(cond) expr
print("Wow! Lucky Guess!") %if% (guess==6)
Racket
Normally, all syntactic forms and functions are in prefix notation. However, two .s allow infix notation in some cases.
#lang racket
(when #t (displayln "true"))
((displayln "true") . when . #t)
(define a 6)
(set! a 5)
(a . set! . 6)
Raku
(formerly Perl 6)
Raku has statement modifiers:
if $guess == 6 { say "Wow! Lucky Guess!" } # Traditional
say 'Wow! Lucky Guess!' if $guess == 6; # Inverted
unless $guess == 6 { say "Huh! You Guessed Rong!" } # Traditional
say 'Huh! You Guessed Rong!' unless $guess == 6; # Inverted
Raku can also invert the syntax of loops:
while $i { --$i }
--$i while $i;
until $x > 10 { $x++ }
$x++ until $x > 10;
for 1..10 { .say if $_ %% 2 }
.say if $_ %% 2 for 1..10; # list comprehension
Raku has a system of metaoperators that modify the characteristics of normal operators. Among these is the R metaoperator, which is able to reverse the arguments of most infix operators (including user-defined ones). So a reversed assignment is easy to write:
42 R= $_; say $_; # prints 42
Since, much like list operators, assignment loosens the precedence of the following expression to allow comma lists, reverse assignment of a list requires parens where the normal assignment would not:
my @a = 1,2,3;
(1,2,3) R= my @a;
However, generally in that case you'd use a feed operator anyway, which is like an object pipe, but unlike Unix pipes works in either direction:
my @a <== 1,2,3;
1,2,3 ==> my @a;
We think this is much more readable than a reversed assignment.
One other interesting inversion is the ability to put the conditional of a repeat loop at either end, with identical test-after semantics:
repeat {
$_ = prompt "Gimme a number: ";
} until /^\d+$/;
repeat until /^\d+$/ {
$_ = prompt "Gimme a number: ";
}
This might seem relatively useless, but it allows a variable to be declared in the conditional that isn't actually set until the loop body:
repeat until my $answer ~~ 42 {
$answer = prompt "Gimme an answer: ";
}
This would require a prior declaration (and two extra semicolons, horrors) if written in the non-inverted form with the conditional at the bottom:
my $answer;
repeat {
$answer = prompt "Gimme an answer: ";
} until $answer ~~ 42;
You can't just put the my on the $answer in the block because the conditional is outside the scope of the block, and would not see the declaration.
REXX
The closest thing that the REXX language has as far as inverted syntax would be the use of the special case of the signal instruction:
SIGNAL {ON|OFF} someCondition {name}
/*REXX program demonstrates a use of a special case of inverted syntax (via SIGNAL ON).*/
signal on syntax
a=7
zz=444 / (7-a)
return zz
/*──────────────────────────────────────────────────────────────────────────────────────*/
syntax: say '***error*** program is attempting to do division by zero,'
say 'the REXX statement number is: ' sigL " and the REXX source is:"
say sourceLine(sigL)
exit 13
output
***error*** program is attempting to do division by zero, the REXX statement number is: 4 and the REXX source is: zz=444 / (7-a)
RPL
Assigning values to variables using →
or STO
commands presents an inverted syntax in RPL. It's also possible to invert syntax for conditional expressions, by pushing the action in the stack as a lambda expression before doing the test, but this isn't idiomatic.
≪ 1 → raining @ Set raining to true ≪ ≪ NEEDUMBRELLA ≫ IF raining THEN EVAL ELSE DROP END @ Execute above action if true, else pop it from stack ≫ ≫ 'TASK' STO @ Store above program in TASK variable
Ruby
Ruby takes, from Perl, the idea of a statement modifier.
This looks like statement if condition
and appends a condition to some statement.
This example shows how to invert if
, unless
, while
and until
.
These always check the condition before running the statement.
# Raise ArgumentError if n is negative.
if n < 0 then raise ArgumentError, "negative n" end
raise ArgumentError, "negative n" if n < 0
# Exit 1 unless we can call Process.fork.
unless Process.respond_to? :fork then exit 1 end
exit 1 unless Process.respond_to? :fork
# Empty an array, printing each element.
while ary.length > 0 do puts ary.shift end
puts ary.shift while ary.length > 0
# Another way to empty an array, printing each element.
until ary.empty? do puts ary.shift end
puts ary.shift until ary.empty?
One can also modify a compound statement, as in (warn "cannot fork"; exit 1) unless Process.respond_to? :fork
.
Beware: The forms begin ... end while ...
and begin ... end until ...
have a different meaning to Ruby.
These forms check the condition after each iteration, so they run the loop at least once. Loops/Do-while#Ruby has more information.
Scala
object Main extends App {
val raining = true
val needUmbrella = raining
println(s"Do I need an umbrella? ${if (needUmbrella) "Yes" else "No"}")
}
Sidef
# Inverted syntax with assignment
var raining = true;
[false]»(\var needumbrella);
# Inverted syntax with conditional expressions
if (raining==true) {needumbrella=true};
{needumbrella=true} -> if (raining==true);
(needumbrella=true) if (raining==true);
Swift
Inverted syntax can be done with custom operators
infix operator ~= {}
infix operator ! {}
func ~=(lhs:Int, inout rhs:Int) {
rhs = lhs
}
func !(lhs:(() -> Void), rhs:Bool) {
if (rhs) {
lhs()
}
}
// Traditional assignment
var a = 0
// Inverted using a custom operator
20 ~= a
let raining = true
let tornado = true
var needUmbrella = false
var stayInside = false
// Traditional conditional expression
if raining {needUmbrella = true}
// Inverted using a custom operator
_ = {stayInside = true} ! tornado
Tcl
Copied verbatim from do.tcl, a part of tcllib's control package.
# do.tcl --
#
# Tcl implementation of a "do ... while|until" loop.
#
# Originally written for the "Texas Tcl Shootout" programming contest
# at the 2000 Tcl Conference in Austin/Texas.
#
# Copyright (c) 2001 by Reinhard Max <Reinhard.Max@gmx.de>
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: do.tcl,v 1.6 2004/01/15 06:36:12 andreas_kupries Exp $
#
namespace eval ::control {
proc do {body args} {
#
# Implements a "do body while|until test" loop
#
# It is almost as fast as builtin "while" command for loops with
# more than just a few iterations.
#
set len [llength $args]
if {$len !=2 && $len != 0} {
set proc [namespace current]::[lindex [info level 0] 0]
return -code error "wrong # args: should be \"$proc body\" or \"$proc body \[until|while\] test\""
}
set test 0
foreach {whileOrUntil test} $args {
switch -exact -- $whileOrUntil {
"while" {}
"until" { set test !($test) }
default {
return -code error \
"bad option \"$whileOrUntil\": must be until, or while"
}
}
break
}
# the first invocation of the body
set code [catch { uplevel 1 $body } result]
# decide what to do upon the return code:
#
# 0 - the body executed successfully
# 1 - the body raised an error
# 2 - the body invoked [return]
# 3 - the body invoked [break]
# 4 - the body invoked [continue]
# everything else - return and pass on the results
#
switch -exact -- $code {
0 {}
1 {
return -errorinfo [ErrorInfoAsCaller uplevel do] \
-errorcode $::errorCode -code error $result
}
3 {
# FRINK: nocheck
return
}
4 {}
default {
return -code $code $result
}
}
# the rest of the loop
set code [catch {uplevel 1 [list while $test $body]} result]
if {$code == 1} {
return -errorinfo [ErrorInfoAsCaller while do] \
-errorcode $::errorCode -code error $result
}
return -code $code $result
}
}
#usage:
package require control
control::do {set i 0; puts "hello world"; incr i} until {$i > 0}
A more radical and probably ill-advised approach is to use the above and modify the default tcl unknown procedure along these lines:
rename unknown __unknown
proc unknown {args} {
if {3 == [llength $args]} {
package require control
return [control::do {*}$args]
} else {
return [__unknown {*}$args]
}
}
#usage
% {set i 0; puts "hello world"; incr i} until {$i > 0}
hello world
TI-83 BASIC
Assignment uses inverted syntax.
536→N
Wortel
The ~
operator reverse the arguments of the next operator.
; a = expr
:a expr
; expr = a
~:expr a
; if cond expr
@if cond expr
; if expr cond
~@if expr cond
Wren
Follows the lines of the Go example which is probably the nearest Wren can get to inverted syntax also.
Again, simulating inverted syntax with assignment is not possible.
class IBool {
construct new(b) {
if (!(b is Bool)) Fiber.abort("B must be a boolean")
_b = b
}
iff(cond) { cond ? _b : !_b }
}
var itrue = IBool.new(true)
var needUmbrella
var raining = true
// normal syntax
if (raining) needUmbrella = true
System.print("Is it raining? %(raining). Do I need an umbrella? %(needUmbrella)")
// inverted syntax
raining = false
needUmbrella = itrue.iff(raining)
System.print("Is it raining? %(raining). Do I need an umbrella? %(needUmbrella)")
- Output:
Is it raining? true. Do I need an umbrella? true Is it raining? false. Do I need an umbrella? false
Z80 Assembly
Syntax on the Z80 is very rigid; macros notwithstanding there is very little support for inverted syntax. However, since the CPU is little-endian, you can store 16-bit data as a word or 2 bytes:
byte &EF,&BE
word &BEEF
Both of the above are equivalent.
zkl
zkl is a OO language so the preferred style is object.method().method()... When a computation needs to be done first, the compose op (colon) can be used maintain the "noun/verb/verb" flow: f() : ... It is also useful to "unwind" computations so they are easier to read but not require any temp vars.
if (raining==True) needumbrella:=True;
(raining==True) : if (_) needumbrella:=True;
a := 6
6 : a:=_
key.sort(fcn(kv,kv2){kv[0] < kv2[0]}) : listUnzip(_) :
D.SD((_).xplode()) : return(_);
- Programming Tasks
- Solutions by Programming Task
- 6502 Assembly
- Ada
- ALGOL 68
- ARM Assembly
- Arturo
- Bracmat
- C
- C++
- Clojure
- CoffeeScript
- Common Lisp
- D
- EchoLisp
- Factor
- Fortran
- FreeBASIC
- Fōrmulæ
- Go
- Haskell
- Icon
- Unicon
- J
- Java
- Jq
- Julia
- Koka
- Kotlin
- Latitude
- Lua
- M2000 Interpreter
- M4
- Mathematica
- Wolfram Language
- Mercury
- Metafont
- Nim
- Oforth
- OxygenBasic
- PARI/GP
- Perl
- Phix
- PicoLisp
- PowerShell
- Prolog
- Python
- Qi
- Quackery
- R
- Racket
- Raku
- REXX
- RPL
- Ruby
- Scala
- Sidef
- Swift
- Tcl
- TI-83 BASIC
- Wortel
- Wren
- Z80 Assembly
- Zkl
- AutoHotkey/Omit
- AWK/Omit
- BBC BASIC/Omit
- Bc/Omit
- Brlcad/Omit
- C sharp/Omit
- Delphi/Omit
- DWScript/Omit
- F Sharp/Omit
- Free Pascal/Omit
- GAP/Omit
- GUISS/Omit
- Lotus 123 Macro Scripting/Omit
- Nemerle/Omit
- NetRexx/Omit
- Pascal/Omit
- UNIX Shell/Omit
- ZX Spectrum Basic/Omit