Programming Language Cheat Sheets: Print

Programming language cheat sheets for 20+ languages. Strings Mathematics [True/False] Operators and Symbols [ternary operator] General (Control Flow/Debugging) Dates Objects [Any.Type/Any.TypeFull] New Features Timelines Documentation Links Sections: Function Examples: Print Note: UFL: Universal Function Library, 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. See lower down for further details.

Function Examples: Print

UFL: FuncDemoPrint [custom 'myprint' function/macro][and print example values]


the code below attempts to create a 'myprint' function/macro
that works more or less identically in each programming language

the code examples below should print the following example values:

print bool array
print string array (or char array) [print \t \n \" etc literally, wrapped in quotes]
print int array
print float array [print negative zero as -0.0 (or -0)] [could support decimal places/significant figures, could require '.0' for floats with integral values)]
print null array
print map (string keys/string values)
print simple object (string properties/string values)

[future changes: string array support could be extended to support char arrays]
[future changes: array support could be extended to support ranges/sets/tuples]

print bool (from array)
print string (from array)
print int (from array)
print float (from array)
print null (from array)
print value from map
print value from simple object

some functions convert (built-in/custom) simple objects to maps to print them,
in other languages, the default print output string is used
[future changes: custom printing may be added for (built-in/custom) simple objects]

for some languages, where available, it would be simpler to use multiple function overloads (or some equivalent), than one giant function
[future changes: this has been added for Rust, and may be done for further languages]

code for dynamically handing all possible types in one function,
can be some of the fiddliest code to write,
some of the functions below are 'miracles',
and insanely complex, despite how relatively simple/short they may look

the main aim of these demos was to produce code,
so that the output of code from different languages,
could be compared directly

==================================================

[AutoHotkey]

myprint(vVar:=unset)
{
	;note: AutoHotkey currently lacks 'null' or an equivalent:
	vDQ := Chr(34)
	vOutput := ""
	if !IsSet(vVar)
		{} ;noop
	else if (Type(vVar) = "String")
		vOutput := vDQ vVar vDQ
	else if (Type(vVar) = "Array")
	{
		for _, vValue in vVar
		{
			if (Type(vValue) = "String")
				vOutput .= vDQ vValue vDQ ", "
			else
				vOutput .= String(vValue) ", "
		}
		vOutput := "[" SubStr(vOutput, 1, -2) "]"
	}
	else if (Type(vVar) = "Map")
	|| (Type(vVar) = "Object")
	{
		for vKey, vValue in (Type(vVar) = "Object" ? ObjOwnProps(vVar) : vVar)
		{
			if (Type(vKey) = "String")
				vOutput .= vDQ vKey vDQ ": "
			else
				vOutput .= String(vKey) ": "

			if (Type(vValue) = "String")
				vOutput .= vDQ vValue vDQ "`r`n"
			else
				vOutput .= String(vValue) "`r`n"
		}
		vOutput := SubStr(vOutput, 1, -2)
	}
	else
		vOutput := String(vVar)
	A_Clipboard .= vOutput "`r`n"
}

oArrayB := [false, true]
oArrayS := ["", "abc", "`"", "a`tb", "a`nb"]
oArrayI := [0, 123]
oArrayF := [-0.0, 0.0, 123.456, -Abs(Ln(0)), Abs(Ln(0)), Abs(Ln(0)/Ln(0))]
oArrayX := [""]
oMapSS := Map("k1","v1", "k2","v2", "k3","v3")
oObjSS := {p1:"v1", p2:"v2", p3:"v3"}

;WARNING: AutoHotkey doesn't have print to console functionality,
;so instead we append to the clipboard:
A_Clipboard := ""

myprint(oArrayB)
myprint(oArrayS)
myprint(oArrayI)
myprint(oArrayF)
myprint(oArrayX)
myprint(oMapSS)
myprint(oObjSS)
myprint()
myprint(oArrayB[1])
myprint(oArrayS[1])
myprint(oArrayI[1])
myprint(oArrayF[1])
myprint(oArrayX[1])
myprint(oMapSS["k1"])
myprint(oObjSS.p1)

MsgBox("done")

==================================================

[C++]

#include <iostream>
#include <string>
#include <map>
#include <type_traits>

struct MyStruct {std::string p1="v1"; std::string p2="v2"; std::string p3="v3";};

void myprint()
{
	std::cout << "\n";
}

//note: 'is_map'/'is_map_v' custom code:
template<typename T> struct is_map : std::false_type {};
template<typename Key, typename Value, typename Compare, typename Allocator> struct is_map<std::map<Key, Value, Compare, Allocator>> : std::true_type {};
template<typename T> constexpr bool is_map_v = is_map<T>::value;

template<typename T>
void myprint(T const& vVar)
{
	std::string vDQ = "\"";
	std::string vNull = "nullptr";
	std::string vOutput = "";
	if constexpr (std::is_same_v<T,std::string>)
		vOutput = vDQ + static_cast<std::string>(vVar) + vDQ;
	else if constexpr (std::is_same_v<T,std::nullptr_t>)
		vOutput = vNull;
	else if constexpr (std::is_same_v<T,bool>)
		vOutput = std::string(vVar ? "true" : "false");
	else if constexpr (std::is_array_v<T>)
	{
		for (const auto& vValue : vVar)
		{
			if constexpr (std::is_same_v<decltype(vValue),const std::string&>)
				vOutput += vDQ + vValue + vDQ + ", ";
			else if constexpr (std::is_same_v<decltype(vValue),std::string *const&>)
				vOutput += (vValue == nullptr ? vNull : *vValue) + ", ";
			else if constexpr (std::is_same_v<decltype(vValue),const bool&>)
				vOutput += std::string(vValue ? "true" : "false") + ", ";
			else if constexpr (std::is_same_v<decltype(vValue),const int&>
			|| std::is_same_v<decltype(vValue),const double&>)
				vOutput += std::to_string(vValue) + ", ";
		}
		vOutput = "[" + vOutput.substr(0, vOutput.length()-2) + "]";
	}
	else if constexpr (is_map_v<T>) //note: 'is_map_v' custom code:
	{
		for (const auto& [vKey,vValue] : vVar)
		{
			if constexpr (std::is_same_v<decltype(vKey),const std::string>)
				vOutput += vDQ + vKey + vDQ + ": ";
			else if constexpr (std::is_same_v<decltype(vKey),std::string *const>)
				vOutput += (vKey == nullptr ? vNull : *vKey) + ": ";
			else if constexpr (std::is_same_v<decltype(vKey),const bool>)
				vOutput += std::string(vValue ? "true" : "false") + ": ";
			else if constexpr (std::is_same_v<decltype(vKey),const int>
			|| std::is_same_v<decltype(vKey),const double>)
				vOutput += std::to_string(vKey) + ": ";
			if constexpr (std::is_same_v<decltype(vValue),const std::string>)
				vOutput += vDQ + vValue + vDQ + ", ";
			else if constexpr (std::is_same_v<decltype(vValue),std::string *const>)
				vOutput += (vValue == nullptr ? vNull : *vValue) + ", ";
			else if constexpr (std::is_same_v<decltype(vValue),const bool>)
				vOutput += (vValue ? "true" : "false") + ", ";
			else if constexpr (std::is_same_v<decltype(vValue),const int>
			|| std::is_same_v<decltype(vValue),const double>)
				vOutput += std::to_string(vValue) + ", ";
		}
		vOutput = "[" + vOutput.substr(0, vOutput.length()-2) + "]";
	}
	else if constexpr (std::is_same_v<T,MyStruct>)
	{
		std::cout << "MyStruct" << "\n";
		return;
	}
	else
	{
		std::cout << vVar << "\n";;
		return;
	}

	std::cout << vOutput << "\n";
}

int main()
{
	bool oArrayB[] = {false, true};
	std::string oArrayS[] = {"", "abc", "\"", "a\tb", "a\nb"};
	int oArrayI[] = {0, 123};
	double oArrayF[] = {-0.0, 0.0, 123.456, -std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity(), std::numeric_limits<double>::quiet_NaN()};
	std::string* oArrayX[] = {nullptr};
	std::map<std::string,std::string> oMapSS = {{"k1","v1"},{"k2","v2"},{"k3","v3"}};
	MyStruct oObjSS;

	myprint(oArrayB);
	myprint(oArrayS);
	myprint(oArrayI);
	myprint(oArrayF);
	myprint(oArrayX);
	myprint(oMapSS);
	myprint(oObjSS);
	myprint();
	myprint(oArrayB[0]);
	myprint(oArrayS[0]);
	myprint(oArrayI[0]);
	myprint(oArrayF[0]);
	myprint(oArrayX[0]);
	myprint(oMapSS.at("k1"));
	myprint(oObjSS.p1);
}

==================================================

[C#]

using System;
using System.Collections.Generic;
using System.Dynamic;

public class Program
{
	public static void myprint()
	{
		Console.WriteLine();
	}
	public static void myprint<T>(T vVar)
	{
		var vDQ = "\"";
		var vNull = "null";
		var vOutput = "";
		if (vVar is String)
			vOutput = vDQ + vVar + vDQ;
		else if (vVar == null)
			vOutput = vNull;
		else if (vVar is Array oArray)
		{
			foreach (var vValue in oArray)
			{
				if (vValue is String)
					vOutput += vDQ + vValue + vDQ + ", ";
				else if (vValue == null)
					vOutput += vNull + ", ";
				else
					vOutput += vValue.ToString() + ", ";
			}
			vOutput = "[" + vOutput.Remove(vOutput.Length-2) + "]";
		}
		else if ((vVar is System.Collections.IDictionary) || (vVar is System.Dynamic.ExpandoObject))
		{
			foreach (var oEntry in (dynamic)vVar)
			{
				var vKey = oEntry.Key;
				var vValue = oEntry.Value;
				if (vKey is String)
					vOutput += vDQ + vKey + vDQ + ": ";
				else if (vKey == null)
					vOutput += vNull + ": ";
				else
					vOutput += vKey.ToString() + ": ";
				if (vValue is String)
					vOutput += vDQ + vValue + vDQ + ", ";
				else if (vValue == null)
					vOutput += vNull + ", ";
				else
					vOutput += vValue.ToString() + ", ";
			}
			vOutput = "[" + vOutput.Remove(vOutput.Length-2) + "]";
		}
		else
			vOutput = vVar.ToString();

		Console.WriteLine(vOutput);
	}

	public static void Main()
	{
		bool[] oArrayB = {false, true};
		string[] oArrayS = {"", "abc", "\"", "a\tb", "a\nb"};
		int[] oArrayI = {0, 123};
		double[] oArrayF = {-0.0, 0.0, 123.456, Double.NegativeInfinity, Double.PositiveInfinity, Double.NaN};
		string[] oArrayX = {null};
		var oDictSS = new Dictionary<string,string> {{"k1","v1"},{"k2","v2"},{"k3","v3"}};
		var oDictSI = new Dictionary<string,int> {{"k1",1},{"k2",2},{"k3",3}};
		dynamic oObjSS = new ExpandoObject();
		foreach (var oEntry in (new Dictionary<string,object>{{"p1","v1"},{"p2","v2"},{"p3","v3"}})) ((IDictionary<string,object>)oObjSS).Add(oEntry);
		dynamic oObjSI = new ExpandoObject();
		foreach (var oEntry in (new Dictionary<string,object>{{"p1",1},{"p2",2},{"p3",3}})) ((IDictionary<string,object>)oObjSI).Add(oEntry);

		myprint(oArrayB);
		myprint(oArrayS);
		myprint(oArrayI);
		myprint(oArrayF);
		myprint(oArrayX);
		myprint(oDictSS);
		myprint(oDictSI);
		myprint(oObjSS);
		myprint(oObjSI);
		myprint();
		myprint(oArrayB[0]);
		myprint(oArrayS[0]);
		myprint(oArrayI[0]);
		myprint(oArrayF[0]);
		myprint(oArrayX[0]);
		myprint(oDictSS["k1"]);
		myprint(oObjSS.p1);
	}
}

==================================================

[Crystal]

def myprint(*oVar)
	if (oVar.size == 0)
		puts
		return
	elsif (oVar.size > 1)
		raise "too many params"
	end

	vVar = oVar[0]? #WARNING: compiler complains if '?' omitted
	vDQ = "\""
	vNull = "nil"
	vOutput = ""
	if (vVar.is_a?(String))
		vOutput = vDQ + vVar + vDQ
	elsif (vVar.nil?)
		vOutput = vNull
	elsif (vVar.is_a?(Array))
		vVar.each do |vValue|
			if (vValue.is_a?(String))
				vOutput += vDQ + vValue + vDQ + ", "
			elsif (vValue.nil?)
				vOutput += vNull + ", "
			else
				vOutput += vValue.to_s + ", "
			end
		end
		vOutput = "[" + vOutput[...-2] + "]"
	elsif (vVar.is_a?(Hash))
		vVar.each do |vKey,vValue|
			if (vKey.is_a?(String))
				vOutput += vDQ + vKey + vDQ + ": "
			elsif (vKey.nil?)
				vOutput += vNull + ": "
			else
				vOutput += vKey.to_s + ": "
			end
			if (vValue.is_a?(String))
				vOutput += vDQ + vValue + vDQ + ", "
			elsif (vValue.nil?)
				vOutput += vNull + ", "
			else
				vOutput += vValue.to_s + ", "
			end
		end
		vOutput = "[" + vOutput[...-2] + "]"
	else
		vOutput = vVar.to_s
	end
	puts vOutput
end

oArrayB = [false, true]
oArrayS = ["", "abc", "\"", "a\tb", "a\nb"]
oArrayI = [0, 123]
oArrayF = [-0.0, 0.0, 123.456, -Float64::INFINITY, Float64::INFINITY, Float64::NAN]
oArrayX = [nil]
oMapSS = {"k1"=>"v1","k2"=>"v2","k3"=>"v3"}
record MyStruct, p1 : String, p2 : String, p3 : String
oObjSS = MyStruct.new("v1", "v2", "v3")

myprint(oArrayB)
myprint(oArrayS)
myprint(oArrayI)
myprint(oArrayF)
myprint(oArrayX)
myprint(oMapSS)
myprint(oObjSS)
myprint()
myprint(oArrayB[0])
myprint(oArrayS[0])
myprint(oArrayI[0])
myprint(oArrayF[0])
myprint(oArrayX[0])
myprint(oMapSS["k1"])
myprint(oObjSS.p1)

==================================================

[Excel]

=IF(ISTEXT(A1),""""&A1&"""",A1)

==================================================

[Excel VBA]

Sub myprint(Optional vVar As Variant)
    If (IsMissing(vVar)) Then
        Debug.Print
        Exit Sub
    End If

    'MAJOR WARNING: 'And' does not apply short-circuit Boolean evaluation:
    vDQ = """"
    vOutput = ""
    If (TypeName(vVar) = "String") Then
        vOutput = vDQ & vVar & vDQ
    ElseIf (IsNull(vVar)) Then
        vOutput = "Null"
    ElseIf (IsArray(vVar)) Then
        For i = LBound(vVar) To UBound(vVar)
            vValue = vVar(i)
            If (TypeName(vValue) = "String") Then
                vOutput = vOutput & vDQ & vValue & vDQ & ", "
            ElseIf (IsNull(vValue)) Then
                vOutput = vOutput & "Null" & ", "
            ElseIf (IsObject(vValue)) Then
                vOutput = vOutput & vValue & ", "
            ElseIf (IsNumeric(vValue) And InStr(1, CStr(vValue), "#")) Then 'note: handle -Inf/Inf/NaN
                vOutput = vOutput & vValue & ", "
            ElseIf ((TypeName(vValue) = "Double") And (vValue = Fix(vValue))) Then
                vOutput = vOutput & WorksheetFunction.Text(vValue, "0.0;-0.0") & ", "
            Else
                vOutput = vOutput & vValue & ", "
            End If
        Next
        vOutput = "[" & Mid(vOutput, 1, Len(vOutput) - 2) & "]"
    ElseIf IsObject(vVar) Then
        vOutput = "" & vVar
    ElseIf (IsNumeric(vVar) And InStr(1, CStr(vVar), "#")) Then 'note: handle -Inf/Inf/NaN
        vOutput = "" & vVar
    ElseIf ((TypeName(vVar) = "Double") And (vVar = Fix(vVar))) Then
        vOutput = WorksheetFunction.Text(vVar, "0.0;-0.0")
    Else
        vOutput = "" & vVar
    End If
    Debug.Print vOutput
End Sub
Sub Macro1()
'
' Macro1 Macro
'

'

On Error Resume Next
Dim vNInf As Double
Dim vInf As Double
Dim vNaN As Double
vNInf = -1# / 0#
vInf = 1# / 0#
vNaN = 0# / 0#
On Error GoTo 0

oArrayB = Array(False, True)
oArrayS = Array("", "abc", """", "a" & vbTab & "b", "a" & vbLf & "b")
oArrayI = Array(0, 123)
oArrayF = Array(-0#, 0#, 123.456, vNInf, vInf, vNaN)
oArrayX = Array(Null)

myprint (oArrayB)
myprint (oArrayS)
myprint (oArrayI)
myprint (oArrayF)
myprint (oArrayX)
myprint
myprint (oArrayB(0))
myprint (oArrayS(0))
myprint (oArrayI(0))
myprint (oArrayF(0))
myprint (oArrayX(0))
End Sub

==================================================

[Go]

package main

import (
	"fmt"
	"math"
	"reflect"
)

// func myprint[T any](oVar ...T) { //WARNING: 'T any': causes errors regarding myprint() type inference, and comparison with nil
func myprint(oVar ...interface{}) {
	if len(oVar) == 0 {
		fmt.Println()
		return
	} else if len(oVar) > 1 {
		panic("too many params")
	}

	vVar := oVar[0]
	vDQ := "\""
	vNull := "nil"
	vOutput := ""
	if fmt.Sprintf("%T", vVar) == "string" {
		vOutput = vDQ + fmt.Sprintf("%v", vVar) + vDQ
	} else if vVar == nil {
		vOutput = vNull
	} else if (reflect.TypeOf(vVar).Kind() == reflect.Slice) || (reflect.TypeOf(vVar).Kind() == reflect.Array) {
		oSliceVal := reflect.ValueOf(vVar)
		// WARNING: special reflection code required to iterate through slice:
		for i := 0; i < oSliceVal.Len(); i++ {
			vValue := oSliceVal.Index(i)
			if vValue.Kind() == reflect.String {
				vOutput += vDQ + fmt.Sprintf("%v", vValue) + vDQ + ", "
			} else if (vValue.Kind() == reflect.Chan || vValue.Kind() == reflect.Func || vValue.Kind() == reflect.Interface || vValue.Kind() == reflect.Map || vValue.Kind() == reflect.Ptr || vValue.Kind() == reflect.Slice) && vValue.IsNil() {
				vOutput += vNull + ", "
			} else {
				vOutput += fmt.Sprintf("%v", vValue) + ", "
			}
		}
		vOutput = "[" + string([]rune(vOutput)[:len([]rune(vOutput))-2]) + "]"
	} else if reflect.TypeOf(vVar).Kind() == reflect.Map {
		oMapVal := reflect.ValueOf(vVar)
		oKeys := oMapVal.MapKeys()
		// WARNING: special reflection code required to iterate through map:
		for _, vKeyVal := range oKeys {
			vKey := vKeyVal.Interface()
			vValue := oMapVal.MapIndex(vKeyVal).Interface()
			if fmt.Sprintf("%T", vKey) == "string" {
				vOutput += vDQ + fmt.Sprintf("%v", vKey) + vDQ + ": "
			} else if vVar == nil {
				vOutput += vNull + ": "
			} else {
				vOutput += fmt.Sprintf("%v", vKey) + ": "
			}
			if fmt.Sprintf("%T", vValue) == "string" {
				vOutput += vDQ + fmt.Sprintf("%v", vValue) + vDQ + ", "
			} else if vVar == nil {
				vOutput += vNull + ", "
			} else {
				vOutput += fmt.Sprintf("%v", vValue) + ", "
			}
		}
		vOutput = "[" + string([]rune(vOutput)[:len([]rune(vOutput))-2]) + "]"
	} else {
		vOutput = fmt.Sprintf("%v", vVar)
	}

	fmt.Println(vOutput)
}

func main() {
	oArrayB := [...]bool{false, true}
	oArrayS := [...]string{"", "abc", "\"", "a\tb", "a\nb"}
	oArrayI := [...]int{0, 123}
	oArrayF := [...]float64{-math.Abs(0.0), 0.0, 123.456, math.Inf(-1), math.Inf(1), math.NaN()}
	oArrayX := []interface{}{nil}
	oMapSS := map[string]string{"k1": "v1", "k2": "v2", "k3": "v3"}
	oObjSS := struct {
		p1 string
		p2 string
		p3 string
	}{"v1", "v2", "v3"}

	myprint(oArrayB)
	myprint(oArrayS)
	myprint(oArrayI)
	myprint(oArrayF)
	myprint(oArrayX)
	myprint(oMapSS)
	myprint(oObjSS)
	myprint()
	myprint(oArrayB[0])
	myprint(oArrayS[0])
	myprint(oArrayI[0])
	myprint(oArrayF[0])
	myprint(oArrayX[0])
	myprint(oMapSS["k1"])
	myprint(oObjSS.p1)
}

==================================================

[Java]

import java.util.*;

class Main
{
	public static class MyClass {public String p1="v1", p2="v2", p3="v3";}

	public static void myprint()
	{
		System.out.println();
	}

	public static <T> void myprint(T vVar)
	{
		var vDQ = "\"";
		var vNull = "null";
		var vOutput = "";
		if (vVar == null)
			vOutput = vNull;
		else if (((Object)vVar).getClass().equals(String.class))
			vOutput = vDQ + vVar + vDQ;
		else if (((Object)vVar).getClass().isArray())
		{
			int vLen = java.lang.reflect.Array.getLength(vVar);
			for (int i = 0; i < vLen; i++)
			{
				Object vValue = java.lang.reflect.Array.get(vVar, i);
				if (vValue == null)
					vOutput += vNull + ", ";
				else if (((Object)vValue).getClass().equals(String.class))
					vOutput += vDQ + vValue + vDQ + ", ";
				else
					vOutput += String.valueOf(vValue) + ", ";
			}
			vOutput = "[" + vOutput.substring(0, vOutput.length()-2) + "]";
		}
		else if ((Object)vVar instanceof Map)
		{
			Map<?,?> oMap = (Map<?,?>)vVar;
			for (Map.Entry<?,?> oEntry : oMap.entrySet())
			{
				var vKey = oEntry.getKey();
				var vValue = oEntry.getValue();
				if (vKey == null)
					vOutput += vNull + ": ";
				else if (((Object)vKey).getClass().equals(String.class))
					vOutput += vDQ + vKey + vDQ + ": ";
				else
					vOutput += String.valueOf(vKey) + ": ";
				if (vValue == null)
					vOutput += vNull + ", ";
				else if (((Object)vValue).getClass().equals(String.class))
					vOutput += vDQ + vValue + vDQ + ", ";
				else
					vOutput += String.valueOf(vValue) + ", ";
			}
			vOutput = "[" + vOutput.substring(0, vOutput.length()-2) + "]";
		}
		else
		{
			//vOutput = String.valueOf(vVar);
			System.out.println(vVar);
			return;
		}

		System.out.println(vOutput);
	}

	public static void main(String[] args)
	{
		boolean[] oArrayB = {false, true};
		String[] oArrayS = {"", "abc", "\"", "a\tb", "a\nb"};
		int[] oArrayI = {0, 123};
		double[] oArrayF = {-0.0, 0.0, 123.456, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN};
		Object[] oArrayX = {null};
		String[][] oEntries = {{"k1","v1"},{"k2","v2"},{"k3","v3"}};
		LinkedHashMap<String,String> oMapSS = Arrays.stream(oEntries).collect(LinkedHashMap::new, (a,e)->a.put(e[0],e[1]), Map::putAll);
		for (String[] e : oEntries) oMapSS.put(e[0], e[1]);
		MyClass oObjSS = new MyClass();

		myprint(oArrayB);
		myprint(oArrayS);
		myprint(oArrayI);
		myprint(oArrayF);
		myprint(oArrayX);
		myprint(oMapSS);
		myprint(oObjSS);
		myprint();
		myprint(oArrayB[0]);
		myprint(oArrayS[0]);
		myprint(oArrayI[0]);
		myprint(oArrayF[0]);
		myprint(oArrayX[0]);
		myprint(oMapSS.get("k1"));
		myprint(oObjSS.p1);
	}
}

==================================================

[JavaScript]

function myprint(...oVar)
{
	if (oVar.length == 0)
	{
		console.log();
		return;
	}
	else if (oVar.size > 1)
		throw new Error("too many params")

	var vVar = oVar[0];
	var vDQ = "\"";
	var vNull = "null";
	var vOutput = "";
	if (typeof vVar == "string")
		vOutput = vDQ + vVar + vDQ;
	else if (vVar === null)
		vOutput = vNull;
	else if ((vVar === 0) && (1/vVar < 0))
		vOutput = "-0";
	else if (Array.isArray(vVar))
	{
		for (vValue of vVar)
		{
			if (typeof vValue == "string")
				vOutput += vDQ + vValue + vDQ + ", ";
			else if (vValue === null)
				vOutput += vNull + ", ";
			else if ((vValue === 0) && (1/vValue < 0))
				vOutput += "-0" + ", ";
			else
				vOutput += vValue.toString() + ", ";
		}
		vOutput = "[" + vOutput.slice(0, -2) + "]";
	}
	else if ((vVar instanceof Map) || (Object.prototype.toString.call(vVar) == "[object Object]"))
	{
		for (const [vKey,vValue] of (vVar instanceof Map) ? vVar : Object.entries(vVar))
		{
			if (typeof vKey == "string")
				vOutput += vDQ + vKey + vDQ + ": ";
			else if (vKey === null)
				vOutput += vNull + ": ";
			else if ((vKey === 0) && (1/vKey < 0))
				vOutput = "-0" + ": ";
			else
				vOutput += vKey.toString() + ": ";
			if (typeof vValue == "string")
				vOutput += vDQ + vValue + vDQ + ", ";
			else if (vValue === null)
				vOutput += vNull + ", ";
			else if ((vValue === 0) && (1/vValue < 0))
				vOutput = "-0" + ", ";
			else
				vOutput += vValue.toString() + ", ";
		}
		vOutput = "[" + vOutput.slice(0, -2) + "]";
	}
	else
		vOutput = vVar.toString();

	//const oRegEx = /(\r\n|\r|\n)/g;
	//document.body.innerHTML += vOutput.replace(oRegEx, "<br>") + "<br>";

	console.log(vOutput);
}

oArrayB = [false, true];
oArrayS = ["", "abc", "\"", "a\tb", "a\nb"];
oArrayI = [0, 123];
oArrayF = [-0.0, 0.0, 123.456, -Infinity, Infinity, NaN];
oArrayX = [null];
oMapSS = new Map([["k1","v1"], ["k2","v2"], ["k3","v3"]]);
oObjSS = {p1:"v1", p2:"v2", p3:"v3"};

myprint(oArrayB);
myprint(oArrayS);
myprint(oArrayI);
myprint(oArrayF);
myprint(oArrayX);
myprint(oMapSS);
myprint(oObjSS);
myprint();
myprint(oArrayB[0]);
myprint(oArrayS[0]);
myprint(oArrayI[0]);
myprint(oArrayF[0]);
myprint(oArrayX[0]);
myprint(oMapSS.get("k1"));
myprint(oObjSS.p1);

==================================================

[Kotlin]

fun myprint(vararg oVar: Any?)
{
	if (oVar.size == 0)
	{
		println()
		return
	}
	else if (oVar.size > 1)
		throw Exception("too many params")

	var vVar = oVar[0]
	var vDQ = "\""
	var vNull = "null"
	var vOutput = ""
	if (vVar is String)
		vOutput = vDQ + vVar + vDQ
	else if (vVar == null)
		vOutput = vNull
	//else if (vVar::class.java.isArray)
	else if (vVar is Array<*>)
	{
		for (vValue in vVar)
		{
			if (vValue is String)
				vOutput += vDQ + vValue + vDQ + ", "
			else if (vValue == null)
				vOutput += vNull + ", "
			else
				vOutput += vValue.toString() + ", "
		}
		vOutput = "[" + vOutput.dropLast(2) + "]"
	}
	else if (vVar is Map<*,*>)
	{
		for ((vKey,vValue) in vVar)
		{
			if (vKey is String)
				vOutput += vDQ + vKey + vDQ + ": "
			else if (vKey == null)
				vOutput += vNull + ": "
			else
				vOutput += vKey.toString() + ": "
			if (vValue is String)
				vOutput += vDQ + vValue + vDQ + ", "
			else if (vValue == null)
				vOutput += vNull + ", "
			else
				vOutput += vValue.toString() + ", "
		}
		vOutput = "[" + vOutput.dropLast(2) + "]"
	}
	else
		vOutput = vVar.toString()
	println(vOutput)
}

var oArrayB = arrayOf(false, true)
var oArrayS = arrayOf("", "abc", "\"", "a\tb", "a\nb")
var oArrayI = arrayOf(0, 123)
var oArrayF = arrayOf(-0.0, 0.0, 123.456, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN)
var oArrayX = arrayOfNulls<Any?>(1)
var oMapSS = mutableMapOf("k1" to "v1", "k2" to "v2", "k3" to "v3")
data class MyDataClass(var dummy:String="") {var p1="v1"; var p2="v2"; var p3="v3"}
var oObjSS = MyDataClass()

fun main()
{
	myprint(oArrayB)
	myprint(oArrayS)
	myprint(oArrayI)
	myprint(oArrayF)
	myprint(oArrayX)
	myprint(oMapSS)
	myprint(oObjSS)
	myprint()
	myprint(oArrayB[0])
	myprint(oArrayS[0])
	myprint(oArrayI[0])
	myprint(oArrayF[0])
	myprint(oArrayX[0])
	myprint(oMapSS["k1"])
	myprint(oObjSS.p1)
}

==================================================

[PHP]

function myprint(...$oVar)
{
	if (count($oVar) == 0)
	{
		echo "\n";
		return;
	}
	else if (count($oVar) > 1)
		throw new Exception("too many params");

	$vVar = $oVar[0];
	$vDQ = "\"";
	$vNull = "null";
	$vOutput = "";
	if (is_string($vVar))
		$vOutput = $vDQ . $vVar . $vDQ;
	else if (is_null($vVar))
		$vOutput = $vNull;
	//if array, with indexes 0 to count-1:
	else if (is_array($vVar) && array_is_list($vVar))
	{
		foreach ($vVar as $vValue)
		{
			if (is_string($vValue))
				$vOutput .= $vDQ . $vValue . $vDQ . ", ";
			else if (is_null($vValue))
				$vOutput .= $vNull . ", ";
			else
				$vOutput .= var_export($vValue, true) . ", ";
		}
		$vOutput = "[" . mb_substr($vOutput, 0, -2) . "]";
	}
	//note: handle 'maps' ('arrays' that fail array_is_list()) and objects:
	else if (is_array($vVar) || ($vVar instanceof stdClass))
	{
		foreach ($vVar as $vKey=>$vValue)
		{
			if (is_string($vKey))
				$vOutput .= $vDQ . $vKey . $vDQ . ": ";
			else if (is_null($vKey))
				$vOutput .= $vNull . ": ";
			else if (($vKey === 0) && (1/$vKey < 0))
				$vOutput = "-0" . ": ";
			else
				$vOutput .= var_export($vKey, true) . ": ";
			if (is_string($vValue))
				$vOutput .= $vDQ . $vValue . $vDQ . ", ";
			else if (is_null($vValue))
				$vOutput .= $vNull . ", ";
			else
				$vOutput .= var_export($vValue, true) . ", ";
		}
		$vOutput = "[" . mb_substr($vOutput, 0, -2) . "]";
	}
	else
		$vOutput = var_export($vVar, true);
	echo $vOutput . "\n";
}

$oArrayB = [false, true];
$oArrayS = ["", "abc", "\"", "a\tb", "a\nb"];
$oArrayI = [0, 123];
$oArrayF = [-0.0, 0.0, 123.456, -INF, INF, NAN];
$oArrayX = [null];
$oMapSS = ["k1"=>"v1", "k2"=>"v2", "k3"=>"v3"];
$oObjSS = (object)["p1"=>"v1", "p2"=>"v2", "p3"=>"v3"];

myprint($oArrayB);
myprint($oArrayS);
myprint($oArrayI);
myprint($oArrayF);
myprint($oArrayX);
myprint($oMapSS);
myprint($oObjSS);
myprint();
myprint($oArrayB[0]);
myprint($oArrayS[0]);
myprint($oArrayI[0]);
myprint($oArrayF[0]);
myprint($oArrayX[0]);
myprint($oMapSS["k1"]);
myprint($oObjSS->p1);

==================================================

[Python]

def myprint(*oVar):
	if (len(oVar) == 0):
		print()
		return
	elif (len(oVar) > 1):
		raise Exception("too many params")

	vVar = oVar[0]
	vDQ = "\""
	vNull = "None"
	vOutput = ""
	if isinstance(vVar, str):
		vOutput = vDQ + vVar + vDQ
	elif vVar is None:
		vOutput = vNull
	elif isinstance(vVar, list):
		for vValue in vVar:
			if isinstance(vValue, str):
				vOutput += vDQ + vValue + vDQ + ", "
			elif vValue is None:
				vOutput += vNull + ", "
			else:
				vOutput += str(vValue) + ", "
		vOutput = "[" + vOutput[:-2] + "]"
	elif (isinstance(vVar, dict) or isinstance(vVar, SimpleNamespace)):
		for vKey,vValue in vVar.items() if isinstance(vVar, dict) else vVar.__dict__.items():
			if isinstance(vKey, str):
				vOutput += vDQ + vKey + vDQ + ": "
			elif vKey is None:
				vOutput += vNull + ": "
			else:
				vOutput += str(vKey) + ": "
			if isinstance(vValue, str):
				vOutput += vDQ + vValue + vDQ + ", "
			elif vValue is None:
				vOutput += vNull + ", "
			else:
				vOutput += str(vValue) + ", "
		vOutput = "[" + vOutput[:-2] + "]"
	else:
		vOutput = str(vVar)
	print(vOutput)

oListB = [False, True]
oListS = ["", "abc", "\"", "a\tb", "a\nb"]
oListI = [0, 123]
oListF = [-0.0, 0.0, 123.456, float("-inf"), float("inf"), float("nan")]
oListX = [None]
oDictSS = {"k1":"v1", "k2":"v2", "k3":"v3"}
from types import SimpleNamespace
oObjSS = SimpleNamespace(**{"p1":"v1", "p2":"v2", "p3":"v3"})

myprint(oListB)
myprint(oListS)
myprint(oListI)
myprint(oListF)
myprint(oListX)
myprint(oDictSS)
myprint(oObjSS)
myprint()
myprint(oListB[0])
myprint(oListS[0])
myprint(oListI[0])
myprint(oListF[0])
myprint(oListX[0])
myprint(oDictSS["k1"])
myprint(oObjSS.p1)

==================================================

[R]

myprint = function(vVar="")
{
	if (nargs() == 0)
	{
		cat("\n")
		return (invisible()) #MAJOR WARNING: 'return ()' would cause myprint() to print NULL
	}

	vDQ = "\""
	vNull = "NULL"
	vOutput = ""
	if ((length(vVar) == 1) && is.character(vVar))
		vOutput = paste0(vDQ, vVar, vDQ)
	else if ((length(vVar) == 0) && is.null(vVar))
		vOutput = vNull
	#note: if negative zero:
	else if ((length(vVar) == 1) && is.numeric(vVar) && !is.na(vVar) && !is.null(vVar) && (vVar == 0) && (1/vVar < 0))
		vOutput = "-0"
	#WARNING: is.vector() returns true for lists and single values like 123/"abc":
	else if ((length(vVar) != 1) && is.vector(vVar) && is.null(names(vVar)))
	{
		for (vValue in vVar)
		{
			if (is.character(vValue))
				vOutput = paste0(vOutput, vDQ, vValue, vDQ, ", ")
			else if (is.null(vValue))
				vOutput = paste0(vOutput, vNull, ", ")
			else if (!is.na(vValue) && !is.null(vValue) && (vValue == 0) && (1/vValue < 0))
				vOutput = paste0(vOutput, "-0", ", ")
			else
				vOutput = paste0(vOutput, vValue, ", ")
		}
		vOutput = paste0("[", substr(vOutput, 1, nchar(vOutput)-2), "]")
	}
	else if (((length(vVar) != 1) && is.vector(vVar) && !is.null(names(vVar))) || (class(vVar) == "MyStruct"))
	{
		vIsObj = (class(vVar) == "MyStruct")
		for (vKey in (if (!vIsObj) names(vVar) else slotNames(vVar)))
		{
			vValue = ifelse(!vIsObj, vVar[[vKey]], slot(vVar, vKey))
			if (is.character(vKey))
				vOutput = paste0(vOutput, vDQ, vKey, vDQ, ": ")
			else if (is.null(vKey))
				vOutput = paste0(vOutput, vNull, ": ")
			else if (is.numeric(vKey) && !is.na(vKey) && !is.null(vKey) && (vKey == 0) && (1/vKey < 0))
				vOutput = paste0(vOutput, "-0", ": ")
			else
				vOutput = paste0(vKey, ": ")
			if (is.character(vValue))
				vOutput = paste0(vOutput, vDQ, vValue, vDQ, ", ")
			else if (is.null(vValue))
				vOutput = paste0(vOutput, vNull, ", ")
			else if (is.numeric(vValue) && !is.na(vValue) && !is.null(vValue) && (vValue == 0) && (1/vValue < 0))
				vOutput = paste0(vOutput, "-0", ", ")
			else
				vOutput = paste0(vOutput, vValue, ", ")
		}
		vOutput = paste0("[", substr(vOutput, 1, nchar(vOutput)-2), "]")
	}
	else
		vOutput = toString(vVar)

	cat(vOutput, "\n", sep="")
}

oVecB = c(FALSE, TRUE)
oVecS = c("", "abc", "\"", "a\tb", "a\nb")
oVecI = c(0, 123)
oVecF = c(-0.0, 0.0, 123.456, -Inf, Inf, NaN)
oListX = list(NULL, NA) #note: lists support multiple types
oMapSS = c("k1"="v1", "k2"="v2", "k3"="v3")
MyStruct = setClass("MyStruct", slots=c(p1="character", p2="character", p3="character"))
oObjSS = MyStruct(p1="v1", p2="v2", p3="v3")

myprint(oVecB)
myprint(oVecS)
myprint(oVecI)
myprint(oVecF)
myprint(oListX)
myprint(oMapSS)
myprint(oObjSS)
myprint()
myprint(oVecB[1])
myprint(oVecS[1])
myprint(oVecI[1])
myprint(oVecF[1])
myprint(oListX[1])
myprint(unname(oMapSS["k1"]))
myprint(slot(oObjSS, "p1"))

==================================================

[Ruby]

def myprint(*oVar)
	if (oVar.size == 0)
		puts
		return
	elsif (oVar.size > 1)
		raise "too many params"
	end

	vVar = oVar[0]
	vDQ = "\""
	vNull = "nil"
	vOutput = ""
	if (vVar.is_a?(String))
		vOutput = vDQ + vVar + vDQ
	elsif (vVar.nil?)
		vOutput = vNull
	elsif (vVar.is_a?(Array))
		for vValue in vVar
			if (vValue.is_a?(String))
				vOutput += vDQ + vValue + vDQ + ", "
			elsif (vValue.nil?)
				vOutput += vNull + ", "
			else
				vOutput += vValue.to_s + ", "
			end
		end
		vOutput = "[" + vOutput[...-2] + "]"
	elsif (vVar.is_a?(Hash) || vVar.is_a?(Struct))
		for vKey,vValue in (vVar.is_a?(Hash) ? vVar : vVar.each_pair)
			if (vKey.is_a?(String))
				vOutput += vDQ + vKey + vDQ + ": "
			elsif (vKey.nil?)
				vOutput += vNull + ": "
			else
				vOutput += vKey.to_s + ": "
			end
			if (vValue.is_a?(String))
				vOutput += vDQ + vValue + vDQ + ", "
			elsif (vValue.nil?)
				vOutput += vNull + ", "
			else
				vOutput += vValue.to_s + ", "
			end
		end
		vOutput = "[" + vOutput[...-2] + "]"
	else
		vOutput = vVar.to_s
	end
	puts vOutput
end

oArrayB = [false, true]
oArrayS = ["", "abc", "\"", "a\tb", "a\nb"]
oArrayI = [0, 123]
oArrayF = [-0.0, 0.0, 123.456, -Float::INFINITY, Float::INFINITY, Float::NAN]
oArrayX = [nil]
oMapSS = {"k1"=>"v1","k2"=>"v2","k3"=>"v3"}
MyStruct = Struct.new("MyStruct", "p1", "p2", "p3")
oObjSS = MyStruct.new("v1", "v2", "v3")

myprint(oArrayB)
myprint(oArrayS)
myprint(oArrayI)
myprint(oArrayF)
myprint(oArrayX)
myprint(oMapSS)
myprint(oObjSS)
myprint()
myprint(oArrayB[0])
myprint(oArrayS[0])
myprint(oArrayI[0])
myprint(oArrayF[0])
myprint(oArrayX[0])
myprint(oMapSS["k1"])
myprint(oObjSS.p1)

==================================================

[Rust][approach 1]

//MAJOR WARNING: creating a custom print macro is very difficult in Rust,
//in essence, code must be valid for any type of variable (for a particular fragment identifier),
//most variables support the Debug trait, i.e. they can be printed using '{:?}',
//such text can be stored as a string, and modified, before printing it via '{}':
use std::any::type_name_of_val;
//use std::collections::HashMap;
use std::collections::BTreeMap; //note: unlike HashMap, prints in a consistent order

macro_rules! myprint
{
	() =>
	{
		println!();
	};
	($val:expr) =>
	{
		match $val
		{
			x if type_name_of_val(&x).starts_with("core::option::Option<") =>
			{
				println!("{:?}", x);
			},
			s if type_name_of_val(&s) == "&str" =>
			{
				//note: rough code to print tabs/newlines:
				let mut t = format!("{:?}", s);
				t = t.replace("\\n", "\n");
				t = t.replace("\\t", "\t");
				println!("{}", t);
			},
			v if type_name_of_val(&v) == "i32"
			|| type_name_of_val(&v) == "i64"
			|| type_name_of_val(&v) == "f64"
			|| type_name_of_val(&v) == "bool" =>
			{
				println!("{:?}", v);
			},
			a if format!("{:?}", a).starts_with("[") && format!("{:?}", a).ends_with("]") =>
			{
				if type_name_of_val(&a).contains("str")
				{
					//note: rough code to print tabs/newlines:
					let mut t = format!("{:?}", a);
					t = t.replace("\\n", "\n");
					t = t.replace("\\t", "\t");
					println!("{}", t);
				}
				else
				{
					println!("{:?}", a);
				}
			},
			m if type_name_of_val(&m).contains("HashMap<")
			|| type_name_of_val(&m).contains("BTreeMap<") =>
			{
				let mut t = format!("{:#?}", m);
				t = t.replace(",\n}", "]");
				t = t.replace(",\n    ", ", ");
				t = t.replace("{\n    ", "[");
				println!("{}", t);
			},
			other =>
			{
				println!("{:?}", other);
			}
		}
	};
}

fn main()
{
	let oArrayB = [false, true];
	let oArrayS = ["", "abc", "\"", "a\tb", "a\nb"];
	let oArrayI = [0, 123];
	let oArrayF = [-0.0, 0.0, 123.456, -std::f64::INFINITY, std::f64::INFINITY, std::f64::NAN];
	let oArrayX = [None as Option<i32>];
	//let oMapSS = HashMap::from([("k1","v1"), ("k2","v2"), ("k3","v3")]);
	let oMapSS = BTreeMap::from([("k1","v1"), ("k2","v2"), ("k3","v3")]);
	#[derive(Debug)]
	struct MyStruct {p1:String, p2:String, p3:String}
	let oObjSS = MyStruct {p1:"v1".to_string(), p2:"v2".to_string(), p3:"v3".to_string()};

	myprint!(oArrayB);
	myprint!(oArrayS);
	myprint!(oArrayI);
	myprint!(oArrayF);
	myprint!(oArrayX);
	myprint!(&oMapSS);
	myprint!(&oObjSS);
	myprint!();
	myprint!(oArrayB[0]);
	myprint!(oArrayS[0]);
	myprint!(oArrayI[0]);
	myprint!(oArrayF[0]);
	myprint!(oArrayX[0]);
	myprint!(oMapSS.get("k1").cloned().unwrap());
	myprint!(oObjSS.p1);
}

==================================================

[Rust][approach 2]

use std::collections::HashMap;
use std::collections::BTreeMap; //note: unlike HashMap, prints in a consistent order

#[derive(Debug)]
struct MyStruct {p1:String, p2:String, p3:String}

fn myprints<T: std::fmt::Debug>(s: T)
{
	let mut t = format!("{:?}", s);
	t = t.replace("\\n", "\n");
	t = t.replace("\\t", "\t");
	println!("{}", t);
}
fn myprintmapss<T: std::fmt::Debug>(m: T)
{
	let mut t = format!("{:#?}", m);
	t = t.replace(",\n}", "]");
	t = t.replace(",\n    ", ", ");
	t = t.replace("{\n    ", "[");
	println!("{}", t);
}
fn myprintarrays<T: std::fmt::Debug>(a: T)
{
	let mut t = format!("{:?}", a);
	t = t.replace("\\n", "\n");
	t = t.replace("\\t", "\t");
	println!("{}", t);
}

use std::fmt::{Debug, Display};
trait CustomPrint {fn custom_print(&self);}
impl CustomPrint for bool {fn custom_print(&self) {println!("{}", self);}}
impl CustomPrint for i32 {fn custom_print(&self) {println!("{}", self);}}
impl CustomPrint for i64 {fn custom_print(&self) {println!("{}", self);}}
impl CustomPrint for f64 {fn custom_print(&self) {println!("{:?}", self);}} //note: '{:?}' for -0.0 instead of -0
impl CustomPrint for Option<i32> {fn custom_print(&self) {println!("{:?}", self);}}
//impl CustomPrint for &str {fn custom_print(&self) {println!("\"{}\"", self);}}
impl CustomPrint for &str {fn custom_print(&self) {myprints(self);}}
impl CustomPrint for String {fn custom_print(&self) {println!("\"{}\"", self);}}
impl<const N: usize> CustomPrint for [bool; N] {fn custom_print(&self) {println!("{:?}", self);}}
impl<const N: usize> CustomPrint for [i32; N] {fn custom_print(&self) {println!("{:?}", self);}}
impl<const N: usize> CustomPrint for [i64; N] {fn custom_print(&self) {println!("{:?}", self);}}
impl<const N: usize> CustomPrint for [f64; N] {fn custom_print(&self) {println!("{:?}", self);}}
impl<const N: usize> CustomPrint for [Option<i32>; N] {fn custom_print(&self) {println!("{:?}", self);}}
//impl<const N: usize> CustomPrint for [&str; N] {fn custom_print(&self) {println!("{:?}", self);}}
impl<const N: usize> CustomPrint for [&str; N] {fn custom_print(&self) {myprintarrays(self);}}
//impl CustomPrint for &BTreeMap<&str, &str> {fn custom_print(&self) {println!("{:?}", self);}}
//impl CustomPrint for &HashMap<&str, &str> {fn custom_print(&self) {println!("{:?}", self);}}
impl CustomPrint for &BTreeMap<&str, &str> {fn custom_print(&self) {myprintmapss(self);}}
impl CustomPrint for &HashMap<&str, &str> {fn custom_print(&self) {myprintmapss(self);}}
impl CustomPrint for &MyStruct {fn custom_print(&self) {println!("{:?}", self);}}
fn myprint<T: CustomPrint>(vVar: T)
{
	vVar.custom_print();
}
fn myprintx() //WARNING: Rust lacks function overloads, so a separate function is needed for 0 parameters
{
	println!();
}

fn main()
{
	let oArrayB = [false, true];
	let oArrayS = ["", "abc", "\"", "a\tb", "a\nb"];
	let oArrayI = [0, 123];
	let oArrayF = [-0.0, 0.0, 123.456, -std::f64::INFINITY, std::f64::INFINITY, std::f64::NAN];
	let oArrayX = [None as Option<i32>];
	//let oMapSS = HashMap::from([("k1","v1"), ("k2","v2"), ("k3","v3")]);
	let oMapSS = BTreeMap::from([("k1","v1"), ("k2","v2"), ("k3","v3")]);
	let oObjSS = MyStruct {p1:"v1".to_string(), p2:"v2".to_string(), p3:"v3".to_string()};

	myprint(oArrayB);
	myprint(oArrayS);
	myprint(oArrayI);
	myprint(oArrayF);
	myprint(oArrayX);
	myprint(&oMapSS);
	myprint(&oObjSS);
	myprintx();
	myprint(oArrayB[0]);
	myprint(oArrayS[0]);
	myprint(oArrayI[0]);
	myprint(oArrayF[0]);
	myprint(oArrayX[0]);
	myprint(oMapSS.get("k1").cloned().unwrap());
	myprint(oObjSS.p1);
}

==================================================

[Scala]

def myprint() =
{
	println()
}

def myprint(vVar:Any) =
{
	var vDQ = "\""
	var vNull = "null"
	var vOutput = ""
	if (vVar.isInstanceOf[String])
		vOutput = vDQ + vVar + vDQ
	else if (!Option(vVar).isDefined)
		vOutput = vNull
	else if (vVar.isInstanceOf[Array[?]])
	{
		for (vValue <- vVar.asInstanceOf[Array[?]])
		{
			if (vValue.isInstanceOf[String])
				vOutput += vDQ + vValue + vDQ + ", "
			else if (!Option(vValue).isDefined)
				vOutput += vNull + ", "
			else
				vOutput += vValue.toString + ", "
		}
		vOutput = "[" + vOutput.substring(0, vOutput.length-2) + "]"
	}
	else if (vVar.isInstanceOf[Map[?,?]] || vVar.isInstanceOf[scala.collection.mutable.LinkedHashMap[?,?]] || vVar.isInstanceOf[MyClass])
	{
		for ((vKey,vValue) <- (if (vVar.isInstanceOf[Map[?,?]]) vVar.asInstanceOf[Map[?,?]] else if (vVar.isInstanceOf[scala.collection.mutable.LinkedHashMap[?,?]]) vVar.asInstanceOf[scala.collection.mutable.LinkedHashMap[?,?]] else Map((for (f<-vVar.getClass.getDeclaredFields) yield {f.setAccessible(true); (f.getName, f.get(vVar))}): _*)))
		{
			if (vKey.isInstanceOf[String])
				vOutput += vDQ + vKey + vDQ + ": "
			else if (!Option(vKey).isDefined)
				vOutput += vNull + ": "
			else
				vOutput += vKey.toString + ": "
			if (vValue.isInstanceOf[String])
				vOutput += vDQ + vValue + vDQ + ", "
			else if (!Option(vValue).isDefined)
				vOutput += vNull + ", "
			else
				vOutput += vValue.toString + ", "
		}
		vOutput = "[" + vOutput.substring(0, vOutput.length-2) + "]"
	}
	else
		vOutput = vVar.toString

	println(vOutput)
}

var oArrayB = Array(false, true)
var oArrayS = Array("", "abc", "\"", "a\tb", "a\nb")
var oArrayI = Array(0, 123)
var oArrayF = Array(-0.0, 0.0, 123.456, Double.NegativeInfinity, Double.PositiveInfinity, Double.NaN)
var oArrayX: Array[String] = Array(null)
var oMapSS = scala.collection.mutable.LinkedHashMap("k1"->"v1", "k2"->"v2", "k3"->"v3")
//var oMapSS = Map("k1"->"v1", "k2"->"v2", "k3"->"v3")
class MyClass(var p1: String="v1", var p2: String="v2", var p3: String="v3")
var oObjSS = new MyClass()

myprint(oArrayB)
myprint(oArrayS)
myprint(oArrayI)
myprint(oArrayF)
myprint(oArrayX)
myprint(oMapSS)
myprint(oObjSS)
myprint()
myprint(oArrayB(0))
myprint(oArrayS(0))
myprint(oArrayI(0))
myprint(oArrayF(0))
myprint(oArrayX(0))
myprint(oMapSS.get("k1").get)
myprint(oObjSS.p1)

==================================================

[SQL (MySQL)]

-- can use (put quotes around non-numeric strings):

WITH t (MyVar) AS (VALUES ROW(false), ROW(true))
SELECT if(CAST(MyVar AS SIGNED)=0 AND MyVar!='0', concat('"',MyVar,'"'), MyVar) FROM t;

WITH t (MyVar) AS (VALUES ROW(''), ROW('abc'), ROW('"'), ROW(concat('a',char(9),'b')), ROW(concat('a',char(10),'b')))
SELECT if(CAST(MyVar AS SIGNED)=0 AND MyVar!='0', concat('"',MyVar,'"'), MyVar) FROM t;

WITH t (MyVar) AS (VALUES ROW(0), ROW(123))
SELECT if(CAST(MyVar AS SIGNED)=0 AND MyVar!='0', concat('"',MyVar,'"'), MyVar) FROM t;

-- WARNING: prints -0.0 and -0.0 as 0:
WITH t (MyVar) AS (VALUES ROW(-0.0), ROW(0.0), ROW(123.456), ROW(-1.7976931348623157E+308), ROW(1.7976931348623157E+308), ROW(1/0))
SELECT if(CAST(MyVar AS SIGNED)=0 AND MyVar!='0', concat('"',MyVar,'"'), MyVar) FROM t;

WITH t (MyVar) AS (VALUES ROW(NULL))
SELECT if(CAST(MyVar AS SIGNED)=0 AND MyVar!='0', concat('"',MyVar,'"'), MyVar) FROM t;

SET @json = '{"p1":"v1", "p2":"v2", "p3":"v3"}';
SELECT j.key_name, json_unquote(json_extract(@json, CONCAT('$.', j.key_name))) AS value
FROM json_table(json_keys(@json, '$'), '$[*]' COLUMNS (key_name VARCHAR(100) PATH '$')) AS j;

==================================================

[SQL (PostgreSQL)]

WITH t (MyVar) AS (VALUES (false), (true))
SELECT (CASE pg_typeof(MyVar)::text WHEN 'text' THEN '"'||MyVar||'"' ELSE ''||MyVar END) FROM t;

WITH t (MyVar) AS (VALUES (''), ('abc'), ('"'), ('a'||chr(9)||'b'), ('a'||chr(10)||'b'))
SELECT (CASE pg_typeof(MyVar)::text WHEN 'text' THEN '"'||MyVar||'"' ELSE ''||MyVar END) FROM t;

WITH t (MyVar) AS (VALUES (0), (123))
SELECT (CASE pg_typeof(MyVar)::text WHEN 'text' THEN '"'||MyVar||'"' ELSE ''||MyVar END) FROM t;

-- WARNING: prints -0.0 and -0.0 as 0:
WITH t (MyVar) AS (VALUES (-0.0), (0.0), (123.456), ('-Infinity'::float), ('Infinity'::float), ('NaN'::float))
SELECT (CASE pg_typeof(MyVar)::text WHEN 'text' THEN '"'||MyVar||'"' ELSE ''||MyVar END) FROM t;

-- WARNING: prints NULL as a blank string:
WITH t (MyVar) AS (VALUES (NULL))
SELECT (CASE pg_typeof(MyVar)::text WHEN 'text' THEN '"'||MyVar||'"' ELSE ''||MyVar END) FROM t;

SELECT key, value
FROM jsonb_each_text('{"p1":"v1", "p2":"v2", "p3":"v3"}'::jsonb) AS t(key, value);

==================================================

[SQL (SQLite)]

//print the rows from single-column tables:
WITH t (MyVar) AS (VALUES (false), (true))
SELECT (CASE typeof(MyVar) WHEN 'text' THEN '"'||MyVar||'"' WHEN 'null' THEN 'NULL' WHEN 'real' THEN iif(MyVar==0 AND atan2(0,MyVar)!=0,'-0.0',MyVar) ELSE MyVar END) FROM t;

WITH t (MyVar) AS (VALUES (''), ('abc'), ('"'), ('a'||char(9)||'b'), ('a'||char(10)||'b'))
SELECT (CASE typeof(MyVar) WHEN 'text' THEN '"'||MyVar||'"' WHEN 'null' THEN 'NULL' WHEN 'real' THEN iif(MyVar==0 AND atan2(0,MyVar)!=0,'-0.0',MyVar) ELSE MyVar END) FROM t;

WITH t (MyVar) AS (VALUES (0), (123))
SELECT (CASE typeof(MyVar) WHEN 'text' THEN '"'||MyVar||'"' WHEN 'null' THEN 'NULL' WHEN 'real' THEN iif(MyVar==0 AND atan2(0,MyVar)!=0,'-0.0',MyVar) ELSE MyVar END) FROM t;

WITH t (MyVar) AS (VALUES (-0.0), (0.0), (123.456), (-1e999), (1e999), (1/0)) -- note: in SQLite, 1/0 returns NULL not NaN)
SELECT (CASE typeof(MyVar) WHEN 'text' THEN '"'||MyVar||'"' WHEN 'null' THEN 'NULL' WHEN 'real' THEN iif(MyVar==0 AND atan2(0,MyVar)!=0,'-0.0',MyVar) ELSE MyVar END) FROM t;

WITH t (MyVar) AS (VALUES (NULL))
SELECT (CASE typeof(MyVar) WHEN 'text' THEN '"'||MyVar||'"' WHEN 'null' THEN 'NULL' WHEN 'real' THEN iif(MyVar==0 AND atan2(0,MyVar)!=0,'-0.0',MyVar) ELSE MyVar END) FROM t;

SELECT (CASE typeof(key) WHEN 'text' THEN '"'||key||'"' WHEN 'null' THEN 'NULL' WHEN 'real' THEN iif(key==0 AND atan2(0,key)!=0,'-0.0',key) ELSE key END)
||': '|| (CASE typeof(value) WHEN 'text' THEN '"'||value||'"' WHEN 'null' THEN 'NULL' WHEN 'real' THEN iif(value==0 AND atan2(0,value)!=0,'-0.0',value) ELSE value END)
FROM json_each('{p1:"v1", p2:"v2", p3:"v3"}');

==================================================

[Swift]

import Foundation
func myprint()
{
	print()
}

//MAJOR WARNING: code duplication required to handle Any versus Any?
//func myprint<T>(_ vVar: T?) //note: also works
func myprint(_ vVar: Any?)
{
	let vDQ = "\""
	let vNull = "nil"
	var vOutput = ""
	if ((vVar is String) || (vVar is Character))
	{
		vOutput = vDQ + (vVar as! String) + vDQ
	}
	else if (vVar == nil)
	{
		vOutput = vNull
	}
	//else if (vVar is Array<String>) //note: a one-liner for convenience, the Array<Any> code below would give the same output
	//{
	//	vOutput = "[\"" + (vVar as! Array<String>).joined(separator:"\", \"") + "\"]"
	//}
	else if (vVar is Array<Any>)
	{
		for vValue in vVar as! Array<Any>
		{
			if ((vValue is String) || (vValue is Character))
			{
				vOutput += vDQ + (vValue as! String) + vDQ + ", "
			}
			else
			{
				vOutput += String(describing:vValue) + ", "
			}
		}
		vOutput = "[" + String(vOutput.dropLast(2)) + "]"
	}
	else if (vVar is Array<Any?>)
	{
		for vValue in vVar as! Array<Any?>
		{
			if ((vValue is String) || (vValue is Character))
			{
				vOutput += vDQ + (vValue as! String) + vDQ + ", "
			}
			else if (vValue == nil)
			{
				vOutput += vNull + ", "
			}
			else
			{
				vOutput += String(describing:vValue) + ", "
			}
		}
		vOutput = "[" + String(vOutput.dropLast(2)) + "]"
	}
	//WARNING: the Dictionary type returns values in a random order, below are 4 conditions for handling common String/Int dictionaries, sorting by key:
	else if (vVar is Dictionary<String,String>)
	{
		//print dictionary in alphabetical order:
		let oArraySS = (vVar as! Dictionary<String,String>).map{($0,$1)}.sorted(by:{e1,e2 in e1.0<e2.0})
		vOutput = "[" + oArraySS.map{vDQ+$0.0+vDQ+": "+vDQ+$0.1+vDQ}.joined(separator:", ") + "]"
	}
	else if (vVar is Dictionary<String,Int>)
	{
		//print dictionary in alphabetical order:
		let oArraySI = (vVar as! Dictionary<String,Int>).map{($0,$1)}.sorted(by:{e1,e2 in e1.0<e2.0})
		vOutput = "[" + oArraySI.map{vDQ+$0.0+vDQ+": "+String($0.1)}.joined(separator:", ") + "]"
	}
	else if (vVar is Dictionary<Int,String>)
	{
		//print dictionary in numerical order:
		let oArrayIS = (vVar as! Dictionary<Int,String>).map{($0,$1)}.sorted(by:{e1,e2 in e1.0<e2.0})
		vOutput = "[" + oArrayIS.map{String($0.0)+": "+vDQ+$0.1+vDQ}.joined(separator:", ") + "]"
	}
	else if (vVar is Dictionary<Int,Int>)
	{
		//print dictionary in numerical order:
		let oArrayII = (vVar as! Dictionary<Int,Int>).map{($0,$1)}.sorted(by:{e1,e2 in e1.0<e2.0})
		vOutput = "[" + oArrayII.map{String($0.0)+": "+String($0.1)}.joined(separator:", ") + "]"
	}
	else if ((vVar is Dictionary<AnyHashable,Any>) || (vVar is MyStruct))
	{
		for (vKey,vValue) in ((vVar is Dictionary<AnyHashable,Any>) ? vVar! as! Dictionary<AnyHashable,Any> : Dictionary<AnyHashable,Any>(uniqueKeysWithValues:Mirror(reflecting:vVar!).children.map{($0!,$1)}))
		{
			if ((vKey is String) || (vKey is Character))
			{
				vOutput += vDQ + (vKey as! String) + vDQ + ": "
			}
			else
			{
				vOutput += String(describing:vKey) + ": "
			}
			if ((vValue is String) || (vValue is Character))
			{
				vOutput += vDQ + (vValue as! String) + vDQ + ", "
			}
			else
			{
				vOutput += String(describing:vValue) + ", "
			}
		}
		vOutput = "[" + String(vOutput.dropLast(2)) + "]"
	}
	else if ((vVar is Dictionary<AnyHashable,Any?>) || (vVar is MyStruct))
	{
		for (vKey,vValue) in (vVar is Dictionary<AnyHashable,Any?>) ? vVar as! Dictionary<AnyHashable,Any?> : Dictionary<AnyHashable,Any?>(uniqueKeysWithValues:Mirror(reflecting:vVar!).children.map{($0!,$1)})
		{
			if ((vKey is String) || (vKey is Character))
			{
				vOutput += vDQ + (vKey as! String) + vDQ + ": "
			}
			else
			{
				vOutput += String(describing:vKey) + ": "
			}
			if ((vValue is String) || (vValue is Character))
			{
				vOutput += vDQ + (vValue as! String) + vDQ + ", "
			}
			else if (vValue == nil)
			{
				vOutput += vNull + ", "
			}
			else
			{
				vOutput += String(describing:vValue) + ", "
			}
		}
		vOutput = "[" + String(vOutput.dropLast(2)) + "]"
	}
	//else if (vVar is Any) //equivalent to line below (in the current context)
	else if (vVar != nil)
	{
		vOutput = String(describing:vVar!)
	}
	else
	{
		vOutput = String(describing:vVar)
	}

	print(vOutput)
}

var oArrayB = [false, true]
var oArrayS = ["", "abc", "\"", "a\tb", "a\nb"]
var oArrayI = [0, 123]
var oArrayF = [-0.0, 0.0, 123.456, -Double.infinity, Double.infinity, Double.nan]
var oArrayX: [Int?] = [nil]
var oDictSS = ["k1":"v1", "k2":"v2", "k3":"v3"]
struct MyStruct {var p1="v1"; var p2="v2"; var p3="v3"}
var oObjSS = MyStruct()

myprint(oArrayB)
myprint(oArrayS)
myprint(oArrayI)
myprint(oArrayF)
myprint(oArrayX)
myprint(oDictSS)
myprint(oObjSS)
myprint()
myprint(oArrayB[0])
myprint(oArrayS[0])
myprint(oArrayI[0])
myprint(oArrayF[0])
myprint(oArrayX[0])
myprint(oDictSS["k1"])
myprint(oObjSS.p1)

==================================================