Inverted syntax: Difference between revisions
m
→{{header|Fōrmulæ}}
(Added Wren) |
|||
(29 intermediate revisions by 12 users not shown) | |||
Line 5:
In traditional syntax conditional expressions are usually shown before the action within a statement or code block:
<
In inverted syntax, the action is listed before the conditional expression in the statement or code block:
<
'''Inverted syntax with assignment'''
Line 15:
In traditional syntax, assignments are usually expressed with the variable appearing before the expression:
<
In inverted syntax, the expression appears before the variable:
<
'''Task'''
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}}==
Line 28 ⟶ 60:
The only place where syntax is kind of inverted is <code>exit when</code> to exit loops:
<
loop
exit when Foo = 10;
Foo := Foo + 1;
end loop;</
=={{header|ALGOL 68}}==
{{works with|ALGOL 68G|Any - tested with release 2.8.win32}}
<
# 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 #
Line 64 ⟶ 96:
( 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 #</
{{out}}
<pre>
Line 71 ⟶ 103:
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.
<
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:
<
3+7:?foo { assigns 10 to foo }
</syntaxhighlight>
=={{header|C}}==
Line 92 ⟶ 153:
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>
Line 109 ⟶ 170:
exit(0);
}
</syntaxhighlight>
Which actually makes the main program look like:
<syntaxhighlight lang="c">
main()
{
Line 135 ⟶ 196:
exit(0);
}
</syntaxhighlight>
To make lint happy you need a /*FALLTHROUGH*/ before the case 0 (in the macro).
Line 141 ⟶ 202:
=={{header|C++}}==
Though rarely, if ever, used in practice, user-defined class types can have inverted syntax with assignment.
<
int data;
public:
Line 162 ⟶ 223:
std::cout << a.getData() << ' ' << b.getData() << '\n';
}</
It doesn't work if the left operand is not of the type <tt>invertedAssign</tt>.
Line 170 ⟶ 231:
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.
<
(if (= 1 1)
(print "Math works."))
Line 181 ⟶ 242:
(->> (print a " is " b)
(let [a 'homoiconicity
b 'awesome]))</
Expanding the macro reveals the nature of the aforementioned limitation.
<
(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.
<
(-> 42 inc (mod 7)))</
=={{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.
<
alert "hello again" unless false # the same as the above; unless is a negated if.
Line 203 ⟶ 264:
idx = 0
arr = (++idx until idx is 10) # same as above; until is an inverted while.</
=={{header|Common Lisp}}==
Line 212 ⟶ 273:
<
(defun unrev-syntax (form)
(cond
Line 221 ⟶ 282:
(defmacro rprogn (&body forms)
`(progn ,@(mapcar #'unrev-syntax forms)))</
Interactive test run:
Line 242 ⟶ 303:
(operator argument*) where argument* is the result of applying the unreversal to the argument:
<
(defun unrev-syntax (form)
(cond
Line 255 ⟶ 316:
(defmacro rprogn (&body forms)
`(progn ,@(mapcar #'unrev-syntax forms)))</
<pre>[1]> (rprogn ((1 + 2) * (3 + 4)))
Line 278 ⟶ 339:
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:
<
import std.algorithm;
Line 291 ⟶ 352:
assert(r.equal([8, 16, 10, 14]));
}</
=={{header|EchoLisp}}==
<
;; use reader macros to transform (a OP b) into (OP b a)
Line 319 ⟶ 380:
compiled :: (#when raining 'umbrella-need)
</syntaxhighlight>
=={{header|Factor}}==
Since code is data in Factor, we can simply reverse it, transforming postfix into "prefix."
<
[ + 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:
<
[ + 2 2 ] pre ! 4</
Of course, this isn't true prefix because <code>+</code> retains its arity of <tt>2</tt>:
<
We can define a more accurate prefix macro for addition and subtraction in terms of <code>reduce</code>:
<
[ + 1 2 3 4 5 ] pre ! 15</
Additionally, using parsing words, we can add any syntax we like. The <code>infix</code> vocabulary is an example of this:
<
[infix
5*(1+1) ! 10
infix]</
=={{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 <
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.
Line 363 ⟶ 424:
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:
<
#Define ThenIf(a, b) If b Then a
Line 375 ⟶ 436:
InvertAssign(a, b)
Print "b is"; b
Sleep</
{{out}}
Line 385 ⟶ 446:
=={{header|Fōrmulæ}}==
'''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}}==
Line 395 ⟶ 466:
Simulating inverted syntax with assignment is not possible.
<
import "fmt"
Line 424 ⟶ 495:
needUmbrella = itrue.iif(raining)
fmt.Printf("Is it raining? %t. Do I need an umbrella? %t\n", raining, needUmbrella)
}</
{{out}}
Line 437 ⟶ 508:
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:
<
action `when` condition = if condition then action else return ()
</syntaxhighlight>
Example usage:
Line 454 ⟶ 525:
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:
<
where y = a * b</
This is in contrast to <code>let</code> expressions, where the definition of local variables comes before the scope that uses them:
<
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'''.
<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.
<
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</
=={{header|J}}==
Line 484 ⟶ 588:
=={{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
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:
<
# or equivalently: o.a = 2</
=={{header|Julia}}==
Line 495 ⟶ 599:
Can be easily implemented as a macro:
<
cond isa Expr && cond.head == :if || throw(ArgumentError("$cond is not an if expression"))
cond.args[2] = expr
Line 501 ⟶ 605:
end
@inv println("Wow! Lucky Guess!") if true else println("Not!") end</
=={{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.
<
infix fun Boolean.iif(cond: Boolean) = if (cond) this else !this
Line 513 ⟶ 643:
val needUmbrella = true iif (raining)
println("Do I need an umbrella? ${if(needUmbrella) "Yes" else "No"}")
}</
{{out}}
Line 524 ⟶ 654:
Latitude, by default, does not support inverted conditionals, as its two primary means of conditional branching both involve the condition first.
<
local 'needUmbrella = False.
Line 533 ⟶ 663:
{ raining. } ifTrue {
needUmbrella = True.
}.</
However, such constructs can easily be added to the language.
<
localize.
if ($1) then {
Line 550 ⟶ 680:
;; 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 <code>local=</code>.
<
local 'a = 6.
Line 560 ⟶ 690:
let 6 = 'b.
println: b. ;; 6</
=={{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}}==
Line 566 ⟶ 707:
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"
Line 621 ⟶ 762:
ExecCond Lazy$(&aa()), A=1
Print x=2
</syntaxhighlight>
=={{header|m4}}==
Line 627 ⟶ 768:
to invert the arguments to the builtin macro, <code>ifelse</code>.
<
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.
Line 642 ⟶ 783:
</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Traditional form:
<syntaxhighlight lang="mathematica">a = 4
->4
Line 653 ⟶ 794:
Print["This was expected"]
]
->This was expected</
Inversion of syntax:
Line 683 ⟶ 824:
These two clauses are exactly the same:
<
progress(Past, Future, At, Total) :-
At = Past + 1,
Line 690 ⟶ 831:
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:
<
example(N) = S :-
from_int(N) = S0,
Line 701 ⟶ 842:
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:
<
io.write_string("Hello, ", IO0, IO1),
io.write_string("world!\n", IO1, IO).
Line 711 ⟶ 852:
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.
Line 717 ⟶ 858:
The order is still enforced by a data dependency, so
<
io.write_string(X, !IO), io.nl(!IO),
some_long_uninteresting_thing(X).
Line 729 ⟶ 870:
main(!IO) :-
io.nl(!IO), io.write_string(X, !IO),
some_long_uninteresting_thing(X).</
=={{header|Metafont}}==
Although there is an assignment operator, you can also define values of variables by equations, such as:
<
7=y;</
Therefore it can be done both ways.
Line 741 ⟶ 882:
Inverted syntax in Nim can be achieved through the use of templates as operators:
<
# if statements
#--
Line 771 ⟶ 912:
# Inverted syntax
6 ~= a</
=={{header|Oforth}}==
Line 782 ⟶ 923:
=={{header|OxygenBasic}}==
Macros may have localised scope, so they can be safely deployed as HumptyDumpty words.
<
macro cond(a,c) {c then a}
Line 800 ⟶ 941:
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.
<
if(raining, print("Umbrella needed"))
fi(->print("Umbrella needed"), raining)</
PARI can also be used to implement it more directly in GP.
Line 815 ⟶ 956:
Perl already has that:
<
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:
<
# 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:
<
$a = $b; # Traditional syntax
assign $b, $a; # Inverted syntax</
Inverted list assignment is not possible because it prevents arrays from flattening.
Line 838 ⟶ 979:
=={{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
<
(append (last Prg) (head -1 Prg)) )</
Test:
<pre>(de needUmbrella (Raining)
Line 889 ⟶ 1,053:
=={{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>
Line 897 ⟶ 1,061:
</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)
{
Line 906 ⟶ 1,070:
say {"Thank God it's Friday!"} -if (Get-Date 5/27/2016).DayOfWeek -eq "Friday"
</syntaxhighlight>
{{Out}}
<pre>
Line 917 ⟶ 1,081:
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.
<
% Also, you become a vampire if someone who is a vampire bites you.
vampire(dracula).
Line 923 ⟶ 1,087:
% Oh no! Dracula just bit Bob...
bites(dracula, bob).</
{{out}}
Line 936 ⟶ 1,100:
=={{header|Python}}==
<
<
something(f)</
=={{header|Qi}}==
<syntaxhighlight lang="qi">
(define set-needumbrella
Raining -> (set needumbrella true) where (= true Raining)
Line 970 ⟶ 1,134:
(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}}==
Line 976 ⟶ 1,166:
This can be done with a simple function.
<
Because R evaluates function arguments lazily, "expr" is never evaluated unless "cond" evaluates to true.
<
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.
<
print("Wow! Lucky Guess!") %if% (guess==6)</
=={{header|Racket}}==
Line 993 ⟶ 1,183:
However, two <tt>.</tt>s allow infix notation in some cases.
<
#lang racket
(when #t (displayln "true"))
Line 1,001 ⟶ 1,191:
(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 lang="raku"
--$i while $i;
Line 1,019 ⟶ 1,210:
for 1..10 { .say if $_ %% 2 }
.say if $_ %% 2 for 1..10; # list comprehension</
So a reversed assignment is easy to write:
<syntaxhighlight lang="raku"
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"
(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:
<syntaxhighlight lang="raku"
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:
<syntaxhighlight lang="raku"
$_ = prompt "Gimme a number: ";
} until /^\d+$/;
Line 1,040 ⟶ 1,231:
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:
<syntaxhighlight lang="raku"
$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:
<syntaxhighlight lang="raku"
repeat {
$answer = prompt "Gimme an answer: ";
} until $answer ~~ 42;</
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.
Line 1,059 ⟶ 1,250:
SIGNAL {ON|OFF} someCondition {name}
</pre>
<
signal on syntax
a=7
Line 1,068 ⟶ 1,259:
say 'the REXX statement number is: ' sigL " and the REXX source is:"
say sourceLine(sigL)
exit 13</
'''output'''
<pre>
Line 1,075 ⟶ 1,266:
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}}==
Line 1,082 ⟶ 1,280:
These always check the condition ''before'' running the statement.
<
if n < 0 then raise ArgumentError, "negative n" end
raise ArgumentError, "negative n" if n < 0
Line 1,096 ⟶ 1,294:
# 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 <code>(warn "cannot fork"; exit 1) unless Process.respond_to? :fork</code>.
Line 1,104 ⟶ 1,302:
=={{header|Scala}}==
<
val raining = true
val needUmbrella = raining
println(s"Do I need an umbrella? ${if (needUmbrella) "Yes" else "No"}")
}</
=={{header|Sidef}}==
<
var raining = true;
[false]»(\var needumbrella);
Line 1,119 ⟶ 1,317:
if (raining==true) {needumbrella=true};
{needumbrella=true} -> if (raining==true);
(needumbrella=true) if (raining==true);</
=={{header|Swift}}==
Inverted syntax can be done with custom operators
<
infix operator ! {}
Line 1,151 ⟶ 1,349:
// Inverted using a custom operator
_ = {stayInside = true} ! tornado</
=={{header|Tcl}}==
Copied verbatim from do.tcl, a part of tcllib's control package.
<
# do.tcl --
#
Line 1,240 ⟶ 1,438:
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:
<
rename unknown __unknown
proc unknown {args} {
Line 1,258 ⟶ 1,456:
% {set i 0; puts "hello world"; incr i} until {$i > 0}
hello world
</syntaxhighlight>
=={{header|TI-83 BASIC}}==
Assignment uses inverted syntax.
<syntaxhighlight lang
=={{header|Wortel}}==
The <code>~</code> operator reverse the arguments of the next operator.
<
:a expr
; expr = a
Line 1,273 ⟶ 1,471:
@if cond expr
; if expr cond
~@if expr cond</
=={{header|Wren}}==
Line 1,279 ⟶ 1,477:
Again, simulating inverted syntax with assignment is not possible.
<
construct new(b) {
if (!(b is Bool)) Fiber.abort("B must be a boolean")
Line 1,300 ⟶ 1,498:
raining = false
needUmbrella = itrue.iff(raining)
System.print("Is it raining? %(raining). Do I need an umbrella? %(needUmbrella)")</
{{out}}
Line 1,307 ⟶ 1,505:
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}}==
Line 1,313 ⟶ 1,519:
It is also useful to "unwind" computations so they are easier to read
but not require any temp vars.
<
(raining==True) : if (_) needumbrella:=True;</
<
6 : a:=_</
<
D.SD((_).xplode()) : return(_);</
|