Julia function argument type def - function

I faced some problem regarding defining the type of arguments for a function in Julia.
From one hand, the code would be faster to run if the type is defined: for example Int64 for an integer number. On the other hand, passing a simple number to the function would needs type cast every time I call the function, e.g. by calling:
convert(a, Int64)
That seems to be an overkill.
what is the advice for good style?

With Julia, it's not generally true that specifying the type for a function's argument(s) will make it faster. If the argument has no type (i.e. Any), or has just an abstract type (for example, Integer instead of Int64, Julia can generate methods for whatever concrete types are actually used to call the function, instead of having to do any conversion.
BTW, the syntax is actually convert(Int64, a), the type you wish to convert to comes first.

Related

A better solution to validate JSON unmarshal to nested structs

There appears to be few options to validate the source JSON used when unmarshalling to a struct. By validate I mean 3 main things:
a required field exists in the JSON
the field is the correct type (e.g. don't force a string into an integer)
the field contains a valid value (value range / enum)
For nested structs, I simply mean where an attribute in one struct has the type of another struct:
type Example struct {
Attr1 int `json:"attr1"`
Attr2 ExampleToo `json:"attr2"`
}
type ExampleToo struct {
Attr3 int `json:"attr3"`
}
And this JSON would be valid:
{"attr1": 5, "attr2": {"attr3": 0}}
To keep this simple, I'll focus simply on integers. The concept of "zero values" is the first issue. I could create an UnmarshalJSON method, which is detected by JSON packages, including the standard encoding/json package. The problem with this approach is that is that is does not support nested structs. If ExampleToo has an UnmarshalJSON method, the ExampleToo.UnmarshalJSON() method is never called if unmarshalling to an Example object. It would be possible to write a method Example.UnmarshalJSON() that recursively handled validation, but that seems extremely complex, especially if ExampleToo is reused in many places.
So there appears to be some packages like the go-playground/validator where validation can be specified both as functions and tags. However, this works on the struct created, and not the JSON itself. So if a field is tagged as validation:"required" on an integer, and the integer value is 0, this will return an error because 0 is both a valid value and the "zero value" for integers.
An example of the latter here: https://go.dev/play/p/zqSUksPzUiq
I could also use pointers for everything, checking for nil as missing values. The main problem with that is that it requires dereferencing on each use and is a pretty uncommon practice for things like integers and strings.
One thing that I have also considered is a "sister struct" that uses pointers to do validation for required fields. The process would basically be to write a validation method for each struct, then validate that sister struct. If it works, then deserialize the main struct (without pointers). I haven't started on this, just a concept I've thought about, but I'm hoping there are better validation options.
So... is there a better way to do JSON/YAML input validation on nested structs? I'm happy to mix methods where say UnmarshalJSON is used for doing some work like verifying fields exist, but I'd like to pass that back to the library to let it continue to call UnmarshalJSON on subsequent nested structs. I'd also rather defer to the JSON library for casting values into the struct, etc.

Which one to use Value vs std::string in cocos2d-x V3 C++?

According to http://www.cocos2d-x.org/wiki/Value,
Value can handle strings as well as int, float, bool, etc.
I'm confused when I have to make a choice between using
std::string
or
Value
In what circumstances should I use Value over std::string, and vice versa??
I think you have misunderstood the Value object. As written in the documentation you linked to:
cocos2d::Value is a wrapper class for many primitives ([...] and std::string) plus [...]
So really Value is an object that wraps a bunch of other types of variables, which allows cocos2d-x to have loosely-typed structures like the ValueMap (a hash of strings to Values - where each Value can be a different type of object) and ValueVector (a list of Values).
For example, if you wanted to have a configuration hash with keys that are all strings, but with a bunch of different values - in vanilla C++, you would have to create a separate data structure for each type of value you want to save, but with Value you can just do:
unordered_map<std::string, cocos2d::Value> configuration;
configuration["numEnemies"] = Value(10);
configuration["gameTitle"] = Value("Super Mega Raiders");
It's just a mechanism to create some loose typing in C++ which is a strongly-typed language.
You can save a string in a Value with something like this:
std::string name = "Vidur";
Value nameVal = Value(name);
And then later retrieve it with:
std::string retrievedName = nameVal.asString();
If you attempt to parse a Value as the wrong type, it will throw an error in runtime, since this is isn't something that the compiler can figure out.
Do let me know if you have any questions.

Storing json, jsonb, hstore, xml, enum, ipaddr, etc fails with "column "x" is of type json but expression is of type character varying"

When using PostgreSQL to store data in a field of a string-like validated type, like xml, json, jsonb, xml, ltree, etc, the INSERT or UPDATE fails with an error like:
column "the_col" is of type json but expression is of type character varying
... or
column "the_col" is of type json but expression is of type text
Why? What can I do about it?
I'm using JDBC (PgJDBC).
This happens via Hibernate, JPA, and all sorts of other abstraction layers.
The "standard" advice from the PostgreSQL team is to use a CAST in the SQL. This is not useful for people using query generators or ORMs, especially if those systems don't have explicit support for database types like json, so they're mapped via String in the application.
Some ORMs permit the implementation of custom type handlers, but I don't really want to write a custom handler for each data type for each ORM, e.g. json on Hibernate, json on EclipseLink, json on OpenJPA, xml on Hibernate, ... etc. There's no JPA2 SPI for writing a generic custom type handler. I'm looking for a general solution.
Why it happens
The problem is that PostgreSQL is overly strict about casts between text and non-text data types. It will not allow an implicit cast (one without a CAST or :: in the SQL) from a text type like text or varchar (character varying) to a text-like non-text type like json, xml, etc.
The PgJDBC driver specifies the data type of varchar when you call setString to assign a parameter. If the database type of the column, function argument, etc, is not actually varchar or text, but instead another type, you get a type error. This is also true of quite a lot of other drivers and ORMs.
PgJDBC: stringtype=unspecified
The best option when using PgJDBC is generally to pass the parameter stringtype=unspecified. This overrides the default behaviour of passing setString values as varchar and instead leaves it up to the database to "guess" their data type. In almost all cases this does exactly what you want, passing the string to the input validator for the type you want to store.
All: CREATE CAST ... WITH FUNCTION ...
You can instead CREATE CAST to define a data-type specific cast to permit this on a type-by-type basis, but this can have side effects elsewhere. If you do this, do not use WITHOUT FUNCTION casts, they will bypass type validation and result in errors. You must use the input/validation function for the data type. Using CREATE CAST is suitable for users of other database drivers that don't have any way to stop the driver specifying the type for string/text parameters.
e.g.
CREATE OR REPLACE FUNCTION json_intext(text) RETURNS json AS $$
SELECT json_in($1::cstring);
$$ LANGUAGE SQL IMMUTABLE;
CREATE CAST (text AS json)
WITH FUNCTION json_intext(text) AS IMPLICIT;
All: Custom type handler
If your ORM permits, you can implement a custom type handler for the data type and that specific ORM. This mostly useful when you're using native Java type that maps well to the PostgreSQL type, rather than using String, though it can also work if your ORM lets you specify type handlers using annotations etc.
Methods for implementing custom type handlers are driver-, language- and ORM-specific. Here's an example for Java and Hibernate for json.
PgJDBC: type handler using PGObject
If you're using a native Java type in Java, you can extend PGObject to provide a PgJDBC type mapping for your type. You will probably also need to implement an ORM-specific type handler to use your PGObject, since most ORMs will just call toString on types they don't recognise. This is the preferred way to map complex types between Java and PostgreSQL, but also the most complex.
PgJDBC: Type handler using setObject(int, Object)
If you're using String to hold the value in Java, rather than a more specific type, you can invoke the JDBC method setObject(integer, Object) to store the string with no particular data type specified. The JDBC driver will send the string representation, and the database will infer the type from the destination column type or function argument type.
See also
Questions:
Mapping postgreSQL JSON column to Hibernate value type
Are JPA (EclipseLink) custom types possible?
External:
http://www.postgresql.org/message-id/54096082.1090009#2ndquadrant.com
https://github.com/pgjdbc/pgjdbc/issues/265
http://www.pateldenish.com/2013/05/inserting-json-data-into-postgres-using-jdbc-driver.html

Are there languages without "null"?

There are many people who think that the concept of the special value null (as it is used in lanuages like C, Java, C#, Perl, Javascript, SQL etc.) is a bad idea. There are several questions about this on SO and P.SE, such as Best explanation for languages without null and Are null references really a bad thing? .
However, I could not find any language that does without them. All the languages I'm familiar with have null, or something similar (e.g. "undefined" in Perl).
I realize that proably every language needs some way to express "absence of a value". However, instead of having "null" or "undefined", this can also be made explicit by using something like Maybe (Haskell) or Optional (Guava). The principal difference to having "null" or "undefined" is that an object can only have "no value" if it has a specific type (Maybe, Optional...). In contrast, "null"/"undefined" is typically a valid value possible for every type.
Are there any languages that do not have nullor a similar concept in this sense?
Here's an incomplete list of languages that are null-safe in the sense that they don't have any non-nonnullable types:
Dart (2021): Has optional types with ? syntax.
C# 8 (2019): Has opt-in "nullable reference types".
Kotlin (2015): Has optional types with ? syntax.
Pony (2015). Uses union type where one of the types is None.
Swift (2014): Has optional types with ? syntax.
Crystal (2014): Does have nil, but prevents all null pointer exceptions at compile-time.
Hack (2014): Has optional types with ? syntax.
TypeScript (2012): Has union types that can have undefined or null as a variant.
Elm (2012): Has union type Maybe.
Ceylon (2011): Has optional types with ? syntax.
Rust (2010): Has optional type Option.
Fantom (2005): Has optional types with ? syntax.
F# (2005): Has union type Option.
Nice (2003): Has optional types with ? syntax.
Netlogo (1999) has no type null
OCaml (1996): Has union type option.
Haskell (1990): Has union type Maybe.
Standard ML (1990): Has union type option.
Tcl (1988)
Erlang (1986)
Prolog (1972): A logical variable stands for "anything at all". There is no concept of "null" or "undefined".
Feel free to complement the list. The years represent the first public release.
Tcl has no concept of null whatsoever. Everything is a value and all values have a string representation (typically summarized as "Everything is a String").
The closest thing to null is the empty string.
To convey the concept of "no value" requires some creativity.
Of course, as mentioned above, some people use the empty string to signify no value. For this to work, empty strings cannot be valid in the data set you're processing. Surprisingly, a lot of real world data falls into this category.
Another way to indicate absence of value is to simply throw an error. In some cases this is exactly what should have been done instead of returning some null or error value (an anti-pattern learned from C and a habit that's hard to get rid of).
Yet another way is to return an empty list (a list is Tcl's equivalent of arrays in other languages). The string representation of an empty list is the empty string. But fortunately the string representation of a list containing an empty string is two double quotes: "\"\"". This difference allows one to differentiate between a list that contains "nothing" and a list that contains a string that has no characters in it.
Finally some people simply indicate the absence of values by simply not declaring the variable (or undeclaring it, which is a thing in tcl). This may sound odd because variables seem to be a compile-time construct (while values are run-time construct) but in tcl everything is run-time. Thus it's possible for code to use non existence of the variable as a signal. Trying to read an undeclared variable results in an error which you can catch. In addition, Tcl also allows you to use introspection to check the state of the interpreter. So you can use [info exist x] to check if a variable called x exists.
V is a newer language with Golang-like syntax that has no nulls.
You already mention Haskell as an example of a language without "null". There are also the languages in the ML family like Standard ML, OCaml or F#. Many dynamically typed languages also do not feature null pointers, scheme would be a good example.

AS3 optimization: Implicit casting vs. "as" in arguments and variable assignments; what's really going on?

It's been shown (e.g. references in AS3: cast or "as") that it's 3-4x faster to use the "as" keyword versus parenthetic casting in AS3. This is because (cast) could better be described as interpolation, actually generating a new object rather than truly casting the old one. (cast) throws a type error if it fails where the "as" operator returns null. Alright.
Three questions here:
(1) What's happening when you pass a Number to a function that expects (int) -- or when you pass a Sprite to a function that expects DisplayObject? i.e. if the function expects a parent class. Is a new, locally scoped object being generated if the expected class is an ascendant of the object you pass as an argument? Is it significantly faster to cast your arguments before calling the function, using "as"?
(2) What's happening in a for each (var i:int in someNumberVector) or a for-each loop treating each Sprite as a DisplayObject, for example? Is every single one re-cast via the slow (not "as" but error-prone) method at each step in the loop?
(3) Does having a function or variable assignment expect an Interface-implementing class (or an Interface itself, e.g. IEventDispatcher) make any difference vs. having it expect a parent class, as far as which method (clone or cast) is used to "cast" the original variable?
When you pass an object of a subtype (or iterate a list of subtypes, etc.), no casting or conversion is required -- the object is that subtype, and can be passed directly. The reason for this is that the memory layout of objects with inheritance is usually implemented as the base object's data, then the next inheriting class's data, etc. plus a vtable pointer to allow method overriding/interface implementation:
// class Sub : Base
obj -> +----------+
|vtable ptr| -. vtable
|----------| `-> +---------+
|Base data | | Method1 |
|----------| +---------+
|Sub data | | Method2 |
+----------+ +---------+
When passing a Sub object, the underlying pointer points to the start of the object in memory -- which is exactly the same as the Base object's start in memory, so there is nothing to do when converting between Sub to Base internally; the only difference is how the variable is used (type checking semantics). The actual object value, and references to it, need absolutely no conversion (in a sane implementation, anyway).
Adding a cast would only slow things down (unless the compiler is smart enough to remove the cast, which it should be, but I don't have much confidence in the optimization capabilities of the AS3 compiler).
However, casting Numbers to ints and vice versa is completely different, as that requires converting the internal representation of the values -- which is slow.
Note the difference between references to objects (where the variable's actual value is just a handle to that object), and value types (where the variable's actual value is the value itself -- no indirection). For example, an int variable holds the actual integer variable, whereas a variable of type Object merely holds a reference to some object. This means that if you use variables of type Object (or untyped variables which are of Object type by default), and try to stick an integer in them, this will cause what's called a "boxing" operation, which takes the value and sticks it into a temporary object so that the variable can keep a reference to it. Manipulating it like an integer (or explicitly casting it), causes that boxed value to be unboxed, which obviously is not instant.
So you can see, casting objects to their base is not slow, because there's no work to do. Casting a base to a derived type is almost as fast (because nothing has to be done to the internal pointer there either), except that a check has to be done to ensure that the object really is of the derived type (resulting in an exception or null depending on what type of cast was done). Casting value types to object types and vice versa is not very fast, because work has to be done to box/unbox the value in addition to a runtime type check. Finally, casting one basic type to another is particularly slow, because the internal representations are completely different, and it takes correspondingly more effort to do the conversion.