summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorpxtom <79592123+pxtom@users.noreply.github.com>2024-05-17 16:08:57 -0400
committerGitHub <noreply@github.com>2024-05-17 14:08:57 -0600
commitab75eeff40a9c73a87c94212a558de870f67535f (patch)
tree9dc23faba48ac3cc99223483877eb46781568663
parent389f2c29565038ded1e8e336d8b6923f1cdd053e (diff)
[phix/en] create (#4131)
-rw-r--r--phix.html.markdown451
1 files changed, 451 insertions, 0 deletions
diff --git a/phix.html.markdown b/phix.html.markdown
new file mode 100644
index 00000000..2a199edd
--- /dev/null
+++ b/phix.html.markdown
@@ -0,0 +1,451 @@
+---
+language: Phix
+contributors:
+ - ["pxtom", "https://gitgub.com/pxtom"]
+filename: learnphix.exw
+---
+
+```
+ -- single line comment
+
+ // single line comment
+
+ /* multi-
+ line comment */
+
+// Start programming immediately
+
+ -- write using UTF8; save as: hello.ex
+ -- use ? for output
+
+ ? "😍 hello , 😎 world!"
+ ? sqrt(2+2)
+
+// Interpret your program
+ /*
+ p hello */
+
+// Compile your program
+ /*
+ p -c hello */
+
+// Coding mistakes receive gentle help messages
+ /*
+ string line
+ line = 5
+ ^ type error (storing atom in string) */
+
+// Every literal value, constant, and variable is an ''object''
+
+ -- a literal object
+ ? "hello"
+ ? PI
+ ? { "hello", PI }
+
+ -- a named variable object
+ object X
+ X = "hello"
+ X = PI
+ X = { "hello", PI }
+
+ -- a named constant object
+ constant myPI = 22/7
+
+// Everything is an ''object'', just two fundemental kinds
+ /*
+ ┌────────────────────▄
+ ┌─┤ object █─┐
+ │ └─▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ │
+ │ │
+ "atom" "container" */
+
+ number x = 3.14159 sequence s = { "hello", PI }
+ integer y = 3 string txt = "hello"
+
+ -- simplify,
+ -- and use only two primitives
+ number x1=3.14156, y1=3
+ sequence s1={"hello",PI}, txt1="hello"
+
+ -- simplify even more,
+ -- and use just one primitive
+ object x2=3.14156, y2=3, s2={"hello",PI}, txt2="hello"
+
+// Elegant data-type design
+
+ -- invent your own "type"
+ -- organize with "struct" or "class"
+ /*
+ ╔═══════════════════════════════╗
+ ║ ┌─────────────────────────┐ ║
+ ║ │ ┌───────────▄ │ ║
+ ║ │ ┌─┤ object █─┐ │ ║
+ ║ │ │ └─▄▄▄▄▄▄▄▄▄▄█ │ │ ║
+ ║ │ │ │ │ ║
+ ║ │ number sequence │ ║
+ ║ │ │ │ │ ║
+ ║ │ integer string │ ║
+ ║ └──────── type ───────────┘ ║
+ ║ ║
+ ╚════════ struct ║
+ class ════════════════╝
+ */
+
+// Syntax is consistant: "keyword...end keyword"
+
+ -- no invisible syntax or extra rules needed.
+
+ // loop
+ -- while ... end while
+
+ integer index = 1
+ while index <= 5 do
+ ? index
+ index += 1
+ end while
+
+ // loop
+ -- for ... end for
+
+ for i=5 to 1 by -1 do
+ ? i
+ end for
+
+ // conditional
+ -- if ... end if
+
+ number p = 4
+ if p < 1 then
+ ? "p is a small number"
+ elsif p > 10 then
+ ? "p is a large number"
+ else
+ ? "p is inbetween"
+ end if
+
+ // conditional
+ -- switch ... end switch
+
+ object ch = prompt_string("enter one character: " )
+ switch ch
+ case "a": ? "ch is a"
+ case "b": ? "ch is b"
+ case "c": ? "ch is c"
+ default: ? "ch is something else"
+ end switch
+
+// Operators are always consistant; never overloaded.
+
+ -- the + operator ''always adds''
+ ? 2+7
+ ? 'A' + 32
+
+ -- the & operator ''always concatenates''
+ ? 2 & 7 --> {2,7}
+ ? "cat" & " " & "dog" --> "cat dog"
+ ? {1,2,3} & "fish" --> {1,2,3} & "fish"
+ pp( {1,2,3} & "fish" ) --> {1,2,3,102'f',105'i',115's',104'h'}
+
+// Use ''sq_'' functions to span entire containers.
+
+ ? sq_add( {1,2,3}, 10 ) --> {11,12,13}
+ ? sq_sqrt( {4,9,16} ) --> {2,3,4}
+
+// Functions must return a value
+
+ function add2( number x, number y )
+ number sum = x + y
+ return sum
+ end function
+ ? add2( 4, 9 )
+
+// Procedures do not return a value
+
+ procedure sum_all( sequence lst )
+ number sum = 0
+ for i=1 to length(lst) do
+ sum += lst[i]
+ end for
+ ? sum
+ end procedure
+ sum_all( {1,3,9,11} )
+
+// Recursion and mutal recursion are permitted
+
+ function factorial(number n)
+ if n == 0 then
+ return 1
+ end if
+ if n<0 then
+ return "error, no negative numbers for factorials"
+ end if
+ return n * factorial(n - 1)
+ end function
+ ? factorial(5)
+
+// User defined data-types
+
+ -- defined like a function: type ... end type
+ -- they are fully programmable; add your own features
+
+ type positive( number x )
+ if not integer(x) then
+ ? "use integers for factorials"
+ return False
+ end if
+ if x < 0 then
+ ? "error, no negative numbers for factorials"
+ return False
+ end if
+ return True
+ end type
+
+ -- use them to declare variables and parameters
+
+ function factorial2( positive n )
+ if n == 0 then return 1 end if
+ return n * factorial2(n-1)
+ end function
+ ? factorial(5)
+
+ -- to catch errors, and recover, use: try ... end try
+
+ try
+ ? factorial2( -5 )
+ catch e
+ ? "that was a mistake"
+ end try
+
+// Sequences are versatile
+
+ -- multiple assignment
+ number a, b, c
+ {a,b,c} = { -100, -200/-2, -300*3 }
+ ? a --> -100
+ ? b --> 100
+ ? c --> -900
+
+ -- swapping values
+ ? a --> -100
+ ? c --> -900
+ {a,c} = {c,a}
+ ? a --> -900
+ ? c --> -100
+
+
+// Symmetrical one-based indexing does it all
+
+ -- both sequence and string are mutable and work alike
+
+ -- 1 2 3 4 5 -- index head to tail
+ s = { 10, 20, 30, 40, 50 }
+ -- -5 -4 -3 -2 -1 -- index tail to head
+
+ // one item
+ ? s[ 2]
+ ? s[-4]
+ -- output for both is:
+ -----> 20
+
+ // slice with one item
+ ? s[ 2.. 2]
+ ? s[-4..-4]
+ -- output for both is:
+ -----> {20}
+
+ // inclusive slice
+ ? s[ 2.. 4]
+ ? s[-4..-2]
+ -- output for both is:
+ -----> {20,30,40}
+
+ // empty sequence
+ ? s[3 .. 2]
+ ? s[-3..-4]
+ -- output for both is:
+ -----> {}
+
+ // insert
+ s[3..2] = {99}
+ ? s
+ -----> {10,20,99,30,40,50}
+
+ // prepend and append
+ s = { 10,20,30,40,50 }
+
+ s[ 1..0] = {0} -- prepend
+ s[$+1..$] = {6} -- append
+
+ ? s
+ -----> {0,10,20,99,30,40,50,6}
+
+ s[0..-1] = {9999} -- append
+
+ ? s
+ -----> {0,10,20,99,30,40,50,6,9999}
+
+ // delete
+ s = { 10,20,30,40,50 }
+
+ s[2..2] = {} -- item deleted
+ ? s
+ -----> {10,30,40,50}
+
+ s[2..3] = {} -- slice deleted
+ ? s
+ -----> {10,50}
+
+// Learn and reuse; you keep what you learn.
+
+ s = { 1,3,5,7 }
+ txt = "jello"
+
+ -- "find" locates one item in either a sequence or a string
+ ? find( 3, s ) --> 2
+ ? find( 'e', txt ) --> 2
+
+ -- "match" locates a slice in either a sequence or a string
+ ? match( {5,7}, s ) -- > 3
+ ? match( "ll", txt ) --> 3
+
+// Look back at the examples, Phix is generic!
+
+// Batteries are installed
+
+ ? sort( {2, 54,6,4, 0} )
+ ? upper( "cat" )
+ ? log( 10.4 )
+ ? trunc(1.4) -- 1
+ ? floor(1.4) -- 1
+ ? trunc(-1.4) -- -1
+ ? floor(-1.4) -- -2
+
+// Batteries are included
+
+ include builtins/regex.e
+
+ string str = "say hello and smile"
+ str = gsub( `s...e`, str, "😍" )
+ ? str --> "say hello and 😍"
+
+// Yes, sequences are "powerful"
+
+ function odd(integer a) return remainder(a,2)=1 end function
+ function even(integer a) return remainder(a,2)=0 end function
+
+ ? tagset(10) --> {1,2,3,4,5,6,7,8,9,10}
+ ? filter(tagset(10),odd) --> {1,3,5,7,9}
+ ? filter(tagset(10),even) --> {2,4,6,8,10}
+
+// A ''struct'' provides named fields, type-checking, and dot notation
+
+ struct point
+ number x = 0
+ number y = 0
+ end struct
+
+ procedure show( point q )
+ printf(1, "(%g,%g)", { q.x, q.y } )
+ end procedure
+
+ point p1 = new()
+ show(p1)
+ --> (0,0)
+
+ p1.x = 3
+ p1.y = 5
+ show( p1 )
+ --> (3,5)
+
+// A ''class'' adds methods and scope control
+
+ class pair
+ public number x = 0
+ public number y = 0
+
+ procedure show( )
+ printf(1, "(%g,%g)", { this.x, this.y } )
+ end procedure
+ end class
+
+ pair p2 = new()
+ p2.show()
+ --> (0,0)
+
+ p2.x = 3
+ p2.y = 5
+ p2.show()
+ --> (3,5)
+
+// Inherit and compose
+
+ class Pair -- any 2 objects
+ public sequence xy
+ public integer x,y
+ function get_x()
+ return xy[1]
+ end function
+
+ function get_y()
+ return xy[2]
+ end function
+ end class
+
+ type pos_seq(sequence x)
+ return min(x) >= 0
+ end type
+
+ class Point extends Pair
+ public pos_seq loc -- any two numbers >= 0
+
+ procedure set_loc(object x)
+ this.xy = {x[1],x[2]}
+ end procedure
+ end class
+
+ class Rectangle extends Point
+ public Point tlc,brc --top_left, bottom_right corners;
+ public sequence size
+
+ function get_size()
+ this.size = {brc.x-tlc.x , brc.y-tlc.y}
+ return this.size
+ end function
+ end class
+
+ Point p1a = new() p1a.loc = {50,10}
+ Point p2a = new() p2a.loc = {300,200}
+
+ Rectangle r = new()
+ r.tlc = p1a
+ r.brc = p2a
+ ? r -- {"struct","Rectangle",4,1}
+ ? r.tlc -- {"struct","Point",3,3}
+
+ ? r.size --> {250,190}
+ ? r.get_size() --> {250,190}
+```
+
+Phix does not (although most can be emulated) directly support
+operator|builtin|function overloading, lambda expressions, closures,
+currying, eval, partial function application, function composition,
+function prototyping, monads, generators, anonymous recursion,
+the Y combinator, aspect oriented programming, interfaces, delegates,
+first class environments, implicit type conversion
+(of the destructive kind), interactive programming, inverted syntax,
+list comprehensions, metaprogramming, pointers
+(other than to raw allocated memory), topic variables,
+enforced singletons, safe mode, s-expressions,
+or formal proof construction.
+
+The author wryly comments:
+
+''That should both scare off and attract the right people''.
+
+
+## References
+
+* [http://phix.x10.mx](http://phix.x10.mx)
+* [Source code](https://github.com/petelomax/Phix)
+* [Forum](https://openeuphoria.org/forum/index.wc)
+* [Rosetta Code](https://rosettacode.org/wiki/Category:Phix)