# Compatibility with Euphoria

Obviously true 100% compatibility is a nonsense idea - you would be forced to reproduce all the bugs, warts, and glitches of the original, and to top that prohibit any improvement.
Instead, 99.9% is more reasonable, but you should bear in mind that means you will have to alter, on average, one line of code in a thousand, and in practice that is roughly what I get when testing code written for Euphoria on Phix. To be fair, sometimes it may be more like 1 line in every 100, which equates to a mere 99.0% compatibility. More recently written code using the very latest 4.1+ features tends to fare less well, but still typically much easier than say migrating from win32lib to arwen or pGUI.
In fact, the Phix compiler tries very hard to give appropriate error and warning messages to ease the translation of legacy code, such as that found in PCAN. When something does not work you should assume the error is actually a helpful clue, and you should ignore warnings at your peril. I have even crippled "without warning" by default in the more recent builds (see pmain.e/DoWithOptions() to restore handling) in the name of legacy code support.
While Euphoria supports (/encourages/touts) implicit sequence operations, Phix expects the programmer to use explicit routines, for example sq_add(x,y) instead of x+y, as detailed in sequence operations. The compiler issues warnings and performs an automatic substitution of the equivalent function-style routine when doing do is irrefutably the correct thing to do, but terminates in error at runtime if the atom-only primitives are passed a sequence. In my experience so far this has not been a significant difficulty, and trivial to fix once detected.
The ",," style optional parameters are not supported by Phix. While, for example, both Phix and Euphoria support myfunc(file), only Euphoria allows myfunc(file,,1) whereas Phix requires the second parameter to be present - and of course it is usually a trivial matter to determine what that should be. In Phix all non-optional parameters must be grouped together on the left hand side of routine parameter declarations.
Euphoria does not support named parameters, for example in Phix both message_box("there", "hi", MB_OK) and message_box(style:=MB_OK,title:="hi",msg:="there") are equivalent. Note that once you start explicitly naming parameters in a call statement you cannot revert to a positional-based method, and there is as yet no way to use named parameters on any of the builtins implemented via #ilASM. See psym.e/symint() and the AutoAsm() calls for a full list of the latter, apart from the sheer number I doubt it would be particularly difficult to figure something out - passing a list of parameter names to AutoAsm should get you started.
Phix does not support forward referencing of variables and constants, though routines are fine. I maintain that forward data references add wholly unnecessary complexity, and evidently cause quite noticable performance loss in the compile phase, in Euphoria, and besides are very easily fixed whenever they cause a problem.
A particular thorn is wxEuphoria which depends on the internal implementation details of Euphoria and it is highly unlikely that a compatibile version of that will become available any time soon.
Wee proved particularly difficult, but I eventually managed to get something working (not yet in the distro).
Many routines in Phix, eg open(), puts(), etc already accept both "fred" and {'f','r','e','d'} but some may have slipped though for reasons of expediency. Feel free to log a bug for that when it seems appropriate.
Phix only supports the absolute least possible pre-processing I could get away with, in the form of ifdef / elsifdef / elsedef. A call such as "if platform()=WINDOWS then" is optimised at compile-time such that no unnecessary code or tests are emitted, which covers 93% of the need for ifdef, plus I disagree with completely separate include files for different operating systems, which is the other 32%. Those percentages include the depressing 57% of cases where ifdef is either ridiculously pointless or the utterly wrong tool to use. To be fair and honest about it, I am being deliberately disparaging to try and deter any extra workload on myself.
All of these (both sets) should be compatible with Eu, which obviously skips PHIX:
WIN32, WINDOWS, LINUX, UNIX, WIN32_GUI, WIN32_CONSOLE, BITS32, BITS64, PHIX
Note that WIN32 === WINDOWS and neither mean 32-bit. Ignored aka omitted by Phix:
FREEBSD, SUNOS, OPENBSD, OSX, SAFE, DATA_EXECUTE, UCSTYPE_DEBUG, CRASH, EU4_0, EU4_1
In other words eg "ifdef FREEBSD" is treated as "if false", or more accurately blanked out as below.
All other ifdefs (currently) trigger a compilation error.
Note that Phix normally abandons parsing when it finds a top-level abort(), however the first ifdef
triggers a preprocessing stage that replaces all ifdef and selected branches with blank lines, and
that can suffer new compilation errors that did not occur with no ifdef before such an abort statement.
The routines listed below have been copied from Euphoria for compatibility reasons. They are only granted the lightest of support and any grief may lead to an offending routine simply being removed rather than fixed. (Don’t panic though, it would take a fairly drastic ding-dong for me to deliberately disrupt other users.) Obviously if I thought these routines were really any good I would adopt them whole-heartedly; the fact they are documented in this section means I have certain reservations about their design or implementation or both.
Of course I would happily accept improved versions of these routines for incorporation into the next release.
Only a few of these routines are supported by pwa/p2js.

canonical_path | - | create a full path to the specified file
prompt_number | - | prompt the user to enter a number
prompt_string | - | prompt the user to enter a string
get | - | read the representation of any Phix object from a file
value | - | read the representation of any Phix object from a string
get_bytes | - | read the next n bytes from a file or device
read_file | - | read a file as a single sequence of bytes
any_key | - | display a prompt to the user and wait for any key
series | - | Create a sequence as a series starting from a given object.
insert | - | Insert an object into a sequence as a new element at a given location.
splice | - | Inserts an object as a new slice in a sequence at a given position. see also javascript.splice
remove | - | Remove an item, or a range of items from a sequence.
remove_all | - | Removes all occurrences of some object from a sequence.
replace | - | Replace a slice in a sequence.
find_replace | - | Find and replace occurences in a sequence.
match_replace | - | Match and replace occurences in a sequence.
to_string | - | Converts an object into a text string.
machine_func | - | Perform a machine-specific operation (not needed in Phix)
machine_proc | - | Perform a machine-specific operation (not needed in Phix)
register_block | - | This routine does nothing in Phix.
unregister_block | - | This routine does nothing in Phix.
map | - | Phix includes a simple shim for partial compatibility
hash | - | Create a hash value from a key

The routines listed below are Phix-specific and do not have Euphoria equivalents of that name.

factorial | - | the factorial of a number
factors | - | the factors of a number
prime_factors | - | the prime factors of a number
get_proc_address | - | low-level common code for define_c_func/proc/var, also used for run-time interpretation of inline assembly
get_proper_dir | - | obtain the full path of a file or directory
get_proper_path | - | obtain the actual longname and full path of a file or directory
get_text | - | read a whole text file as a string or sequence of lines
machine_bits | - | determine 32 or 64 bit operation. (likewise machine_word, as documented on the same page)
scanf | - | construct (all) the possible param sequence(s) such that printf could produce the given string
set_mb_hwnd | - | specify a default hwnd for message_box (windows only)
string | - | note that Euphoria does not have an 8-bit string type
substitute | - | replace all instances of a substring
tagset | - | return a sequence of integers 1..n
See also | - | multithreading, sequence ops

The routines listed below have important differences between Phix and Euphoria.

flatten | - | Phix does not support (the broken) delimiter parameter, use join() instead
min | - | in Phix min(s) is an alias for minsq(s) [nb: not achievable using optional parameters]
max | - | in Phix max(s) is an alias for maxsq(s) [nb: not achievable using optional parameters]

The routines listed below are deliberately omitted from Phix.

allocate_pointer_array free_pointer_array | - | trailing null, allocate/free contents, and similar questions make these ambiguous, and better off being application specific.
slice | - | The Euphoria version treats a stop of 0 as the last element and -1 as one before that, whereas Phix would naturally use -1 and -2. Plus it "corrects" out-of-range inputs whereas I feel it makes much more sense (both safer and faster) just to use s[start..stop], and get the indexes right/within bounds in the first place. Hence there is deliberately no equivalent routine provided with Phix. See also: javascript.slice