The Universal Function Library Project

Introduction

The UFL, Universal Function Library, is a set of around 100-300 standard functions for all programming languages. Languages do not have to implement anything exactly to the UFL specification, it is a guide. In addition, a small number of recommendations are made regarding operators and statements. See below. Furthermore, some recommendations regarding specific programming languages are made. See below.

General Recommendations: Operators and Statements

All programming languages should have the following: a standard ternary operator (use alternative symbols if '?' and ':' aren't available): c ? x : y [C uses c ? x : y][Raku uses c ?? x !! y][perhaps c ??? x : y][perhaps c ??? x ::: y] a short ternary operator x ?: y [PHP uses x ?: y][JavaScript uses x || y][equivalent to x ? x : y] a swap statement or function: swap var1 var2 Swap(&var1, &var2) [Swift uses swap(&a, &b)][C++ uses std::swap(a, b)] a noop statement or function: noop [Python uses pass] Noop() 2 mod operators: a % b [C-style mod][C uses %][more common, but less useful: for positive b, the return value is positive, 0 or negative (depending on the sign of a)] a %% b [floor mod][R uses %%][Python uses %][more useful: for positive b, the return value is always positive or 0] 3 integer division operators for integers and floats: a / b [true divide][returns a float][use an alternative symbol if / does C-style integer division][returning a float is more intuitive, and pretty common (e.g. JavaScript/PHP/Python)][truncating the return value breaks the principle of least astonishment, and often leads to bugs] a ~/ b [C-style integer divide][Dart uses ~/] a ~~/ b [floor divide][Python uses //][perhaps ~//][perhaps _/][there may be a better symbol than ~~/] See the relevant pages for more details: Programming Language Comparison: General (Control Flow/Debugging) Programming Language Comparison: Operators and Symbols

General Recommendations: Functions and Methods

common debugging functions: ● Print: a good variable print function, either the main print function, or an additional function, that can display the contents of primitives/strings/arrays/maps etc (full depth by default, perhaps with a depth parameter) (appends linefeed by default) ● Type: succinct 'get variable type' functions, that work on all variables (perhaps 2 versions, short name, and full name) ● Version/LangVersion: a well-thought out, version number function, to report the programming language version number, the one function that must be designed right first time (e.g. it just returns a friendly string e.g. '1.2.3.4', or it returns an object, where one member is a friendly string) (new version functions may be added, but old version functions must not be removed/modified to be backwards incompatible) key string functions that should be more widespread: ● StrStarts/StrEnds ('StrStartsWith'/'StrEndsWith') (avoids verbosity and arithmetic errors with string slicing, makes the intention clear) ● ... in addition, StrContains ('StrIncludes'), is shorter, more readable and more intuitive than (StrIndexOf() != -1) ● ... and to complete the set, StrEquals, is more intuitive than !StrCompare() and allows for a case-sensitivity parameter, unlike 'str1 == str2' ● StrCount (PHP uses substr_count, Python uses str.count), e.g. do a line count, useful in algorithms ● StrRept (JavaScript uses repeat, PHP uses str_repeat), e.g. indent text, useful in speed tests, useful in unit tests and demo scripts, useful in algorithms ● SubStr/StrSlice: languages should have both of: SubStr (pos/length) and StrSlice (pos1/pos2) key mathematical functions that should be more widespread: ● FloorMod (extremely useful) ● Sign/Clamp (they make the intention clearer, avoid bugs, and can be useful for writing readable one-liners) ● VerCompare/IPCompare (compare version numbers/IP addresses, return negative/0/positive) ● PopCount (useful for algorithms, and useful for tight loops where speed matters) ● MRound (round to the nearest multiple of n) ● Combin/Permut ● Gamma ● Erf ● Between See the relevant pages for more details: Programming Language Comparison: Strings Programming Language Comparison: Mathematics Programming Language Comparison: Dates Programming Language Comparison: Objects

Specific Language Recommendations

AutoHotkey: ● add Array methods: Sort/Reverse/Swap, Join, Map/Reduce/ReduceRight/Filter, IndexOf/LastIndexOf ● add a Range object C++: ● add a short-ternary operator (Elvis operator) (e.g. 'a ?: b') (equivalent to 'a || b' in JavaScript, and 'a ?: b' in PHP) that returns the first truthy value or the last falsey value, rather than a boolean) ● add some form of Array.Join() (that can at least handle string/integer/float values) ● add an insertion-order map (dictionary) C#: ● make dec to/from base conversions possible for all bases 2-36 (Convert.ToString/Convert.ToInt32 only handle bases 2/8/10/16) ● add a short-ternary operator (Elvis operator) (e.g. 'a ?: b') (equivalent to 'a || b' in JavaScript, and 'a ?: b' in PHP) that returns the first truthy value or the last falsey value, rather than a boolean) ● (add a spread operator for function calls) (note: awaiting confirmation: the '..' operator may fulfil this role in future) Excel: ● add a sheet function to count string occurrences (working name: 'TEXTCOUNT') Go: ● implement a standard ternary operator (use alternative symbols to ? and : if necessary, like Raku) Java: ● add a standard Round method (e.g. 1.5/0.5/-0.5/-1.5 etc should always round away from zero) ● add object properties (i.e. 'obj.myprop = value' and 'value = obj.myprop'), where myprop is either a standard property or is defined by getter/setter methods (versus the verbose-to-define/verbose-to-increment/less-maintainable-rename-it-3-times/parallel-collections-anti-pattern 'obj.setmyprop(value)' and 'value = obj.getmyprop()' convention) ● allow specifying default function parameters (or some convenient/succinct alternative) ● add a short-ternary operator (Elvis operator) (e.g. 'a ?: b') (equivalent to 'a || b' in JavaScript, and 'a ?: b' in PHP) that returns the first truthy value or the last falsey value, rather than a boolean) ● (add a spread operator for function calls) ● (subscript/subscript-like syntax for maps/dictionaries) (the clunkiness of method syntax makes them off-putting to work with (e.g. getting/setting/incrementing/appending), and doesn't play well when working in multiple languages) ● (add C++-style pairs or similar) JavaScript: ● add a function for creating date strings from parts (e.g. AutoHotkey: FormatTime(d, "ddd yyyy-MM-dd HH:mm:ss"), e.g. Python: d.strftime("%a %Y-%m-%d %H:%M:%S %z")) ● add a function for creating strings from parts (e.g. AutoHotkey: Format("{:02}:{:02}:{:02}", 1, 2, 3), e.g. Python: "{:02d}:{:02d}:{:02d}".format(1, 2, 3)) (note: padStart is too verbose for use with multiple values simultaneously, and doesn't play well with negative numbers) ● (subscript/subscript-like syntax for maps/dictionaries) (the clunkiness of method syntax makes them off-putting to work with (e.g. getting/setting/incrementing/appending), and doesn't play well when working in multiple languages) ● (add a function to return the variable's type, e.g. 'Array'/'Map'/'Object' rather than 'object') Kotlin: ● add a standard Round method (e.g. 1.5/0.5/-0.5/-1.5 etc should always round away from zero) ● implement a standard ternary operator (use alternative symbols to ? and : if necessary, like Raku) ● add a short-ternary operator (Elvis operator) (e.g. 'a ?: b') (equivalent to 'a || b' in JavaScript, and 'a ?: b' in PHP) that returns the first truthy value or the last falsey value, rather than a boolean) ● (subscript/subscript-like syntax for maps/dictionaries) (the clunkiness of method syntax makes them off-putting to work with (e.g. getting/setting/incrementing/appending), and doesn't play well when working in multiple languages) PHP: ● (array_reduce(): add the ability to have the first item be the initial accumulator, can currently specify a value, or specify null) Python: ● add a string slice method (the unusual 's[i,j]' slice syntax, doesn't play well when working across multiple programming languages) ● implement a standard ternary operator (use alternative symbols to ? and : if necessary, like Raku) (particularly as it's such a mathematical language, it's frustrating that Python currently lacks this) ● add && and || operators (clearer/easier to find than 'and'/'or') ('&&' is shorter than 'and') (also useful when working across multiple programming languages) ● add a join method to 'list' objects (that can at least handle string/integer/float values) ● partially reimplement the print statement ('print myVar'), to print strings/numbers/lists/dictionaries (useful for testing code when coding at speed, and to speed up the manual (non-automated) conversion of Python 2 scripts (by avoiding countless nags), and to avoid copying-and-pasting a trailing ')') ● add a string repeat method (the unusual 's * n'/*n * s' repeat syntax, doesn't play well when working across multiple programming languages) ● (more succinctly handle sort comparator functions that return negative/0/positive) ● (add an inclusive range function) (working name: 'rangeinc') ● (add a 'getOrDefault'/'getOrElse' method to 'list' objects for indexes that are out of bounds) (e.g. allow specifying a fallback value, or perhaps a fallback function, that receives the index and outputs a value) (without this, 1-liners become try/catch 4-liners) ● (add a 'rindex'/'lastindex' method to 'list' objects, a right-to-left version of 'index') Rust: ● implement a standard ternary operator (use alternative symbols to ? and : if necessary, like Raku) Swift: ● add a short-ternary operator (Elvis operator) (e.g. 'a ?: b') (equivalent to 'a || b' in JavaScript, and 'a ?: b' in PHP) that returns the first truthy value or the last falsey value, rather than a boolean) ● add an insertion-order dictionary (map) (e.g. as the default, as an option, or as a separate class) ● add a more succinct way to perform a string slice ● (more succinctly handle sort comparator functions that return negative/0/positive) ● (add a spread operator for function calls)