Qore Programming Language

  • Increase font size
  • Default font size
  • Decrease font size

Qore 0.8.0 RELEASE-NOTES

E-mail Print PDF

RELEASE NOTES for qore v0.8.0 aka "Hard Qore"

release summary: major Qore release with significant new functionality; see below for compatibility warnings

  • hard typing, function and method overloading, and default argument values

declaring a variable with type info:
ex:

      our int $i = 1;
      # the following 2 are functionally identical
      my Mutex $m = new Mutex();
      my Mutex $m();

declaring a function with argument types, default argument values and return types:
ex:

 sub example(int $i = 0, bool $force = False) returns string {
  return "test";
 }


builtin types: int, float, bool, string, hash, object, reference, binary, date, nothing, null

soft types:
softint: converts automatically from string, float, bool, and date
softbool: converts automatically from string, float, int, and date
softstring: converts automatically from int, float, bool, and date
softfloat: converts automatically from string, int, bool, and date

composite types:
data: either string or binary
any: any value (including nothing)
code: either a call reference or a closure

the special type names "callref" and "closure" are synonyms for "code" and cannot be used to restrict a value to one or the other types.

limitations of hard typing:
no complex types are available yet (reference to hash, list of Condition, etc).
many functions and methods can return more than one data type depending on the arguments (values, not types); in this case the return types are tagged as "any" even though only a small number of types can be returned.  In general, whenever an expression can return more than one type, this is currently covered by returning type "any".

Type information has been propagated through the parser; so many more errors can be caught at parse time, sometimes even if types are not declared in code (such as with code written for older versions of qore, for example).  See below for warnings (non-existent-method-call, invalid-operation, call-with-type-errors, return-value-ignored, deprecated, excess-args, duplicate-hash-key) and parse directives (ex %require-types) added, most of them related to typing.

class methods restrictions: the following methods may not be overloaded:
<class>::copy()
<class>::destructor()
<class>::memberNotification(string $member)
<class>::memberGate(string $member)
<class>::methodGate(string $method, ...)

  • time zone support in absolute date/time values

Qore uses the system's zoneinfo information to determine the UTC offset and daylight saving's time changes
Dates given without a time zone portion are assumed to be in local time

  • more flexible time input when parsing:

UTC offset in time east plus hundreths of a second (1-6 digits after the decimal point are accepted):
2001-01-01T11:35:21.53+06:00

date in Zulu time (UTC) (time component = 00:00:00Z)
2001-01-01Z

  • date/time values have resolution to the microsecond

previously was to the millisecond; applies to both relative and absolute date/time values

parser accepts a new relative time format: <x>us, ex: 45us = 45 microseconds

  • conversion to a date from a string is much more flexible

formats such as the following are now accepted:

2001-01-01T15:35:23         # 2001-01-01 15:35:23 Mon +01:00 (CET)
20010101 15:35:23Z          # 2001-01-01 15:35:23 Mon Z (UTC)
20010101 153523Z            # 2001-01-01 15:35:23 Mon Z (UTC)
20010101 153523-02          # 2001-01-01 15:35:23 Mon -02:00 (-02:00)
20010101 153523-02:00:00    # 2001-01-01 15:35:23 Mon -02:00 (-02:00)
2001-01-01-153523-020000    # 2001-01-01 15:35:23 Mon -02:00 (-02:00)
20010101-153523             # 2001-01-01 15:35:23 Mon +01:00 (CET)

etc

furthermore, it's now possible to directly specify relative date/time values when converting from a string using a subset of ISO-8601 duration formats with an extension for microseconds (<n>u - the 'u' is lower-case as it is not part of the ISO9601 standard) and also an extension where the numeric portion may be negative:

P<n>Y<n>M<n>DT<n>H<n>M<n>S<n>u


for example:

P1Y2MT4H                    # <time: 1 year 2 months 4 hours>
P4DT-2M15u                  # <time: 4 days -2 minutes 15 microseconds>
PT4H30M                     # <time: 4 hours 30 minutes>


note that there must be at least one time component, and the <n>M value is minutes when following the 'T' and months when preceding or in the absense of a 'T'.
unlike ISO-8601 durations, all numbers must be integers (ISO-8601 allows the smallest time unit given to have a fractional component)

The other duration format: PYYYY-MM-DDTHH:MM:SS is also still accepted as well as in previous versions of qore

  • class constuctor methods can now be declared private

  • new TimeZone class

# creates a TimeZone object based on a zoneinfo region file
TimeZone::constructor(string)

# creates a TimeZone object based on a UTC offset in seconds east of UTC
TimeZone::constructor(softint)

# returns a date marked with this TimeZone from the UTC offset in seconds
TimeZone::date(softint $epoch_seconds, softint $us = 0)

# returns a date marked with this TimeZone
TimeZone::date(date)

# returns a date marked with this TimeZone from the given argument as an epoch offset in milliseconds
TimeZone::dateMs(softint)

# returns a date marked with this TimeZone from the given argument as an epoch offset in microseconds
TimeZone::dateUs(softint)

# returns the time zone for the current execution context
static TimeZone::get() returns TimeZone

# allows the time zone to be set for the current execution context
static TimeZone::set(TimeZone) returns nothing

# sets the time zone according to a UTC offset in seconds east of UTC for the current execution context
static TimeZone::setUTCOffset(softint) returns nothing

# sets the time zone according to a zoneinfo region file for the current execution context
static TimeZone::setRegion(string) returns nothing
  • new Program methods

Program::setTimeZoneRegion(string)
Program::setTimeZoneUTCOffset(softint)
Program::setTimeZone(TimeZone)
Program::getTimeZone() returns TimeZone
  • new functions

getpwuid2(softint) returns hash
getpwnam(string) returns any
getpwnam2(string) returns hash
getgrgid(softint) returns any
getgrgid2(softint) returns hash
getgrnam(string) returns any
getgrname2(string) returns hash
readlink(string) returns string
is_date_relative(date) returns bool
is_date_absolute(date) returns bool
get_duration_seconds(date) returns int
get_duration_milliseconds(date) returns int
get_duration_microseconds(date) returns int
now_us() returns date
now_utc() returns date
date_us(softint) returns date
microseconds(softint) returns date
get_microseconds(date) returns int
get_epoch_seconds(date) returns int
setsid() returns int
  • new overloaded variants of existing functions

gmtime(date) returns date
localtime(date) returns date
  • new Socket methods and variants

Socket::connectINET(string $host, int $port, int $timeout_ms = -1) returns nothing
Socket::connectINET(string $host, int $port, date $timeout_ms) returns nothing
Socket::connectINETSSL(string $host, int $port, int $timeout_ms = -1) returns nothing
Socket::connectINETSSL(string $host, int $port, date $timeout_ms) returns nothing
Socket::connectUNIX(string $path) returns nothing
Socket::connectUNIXSSL(string $path) returns nothing
Socket::setCertificate(binary) returns nothing
Socket::setCertificate(string) returns nothing
Socket::setPrivateKey(binary) returns nothing
Socket::setPrivateKey(string) returns nothing
  • new object creation syntax

to create an object without explicitly using the "new" operator, use the "my" or "our" keywords then give the class name followed by the arguments to the constructor in parentheses as in the following example:
my File $f();

  • cast<> operator

This operator can be used to suppress warnings such as the non-existent-method-call warning; for example, if you make a method call from a base class to a method that only exists in a subclass, because qore has no way of defining "pure virtual" methods like in C++, the parser raises a "non-existent-method-call" warning.  You can use the cast<> operator to supress this warning as in the following example:
cast<ChildClass>($self).methodCall();

  • delete statement is now the delete operator

so now the delete operator can be used in "map" expressions, for example

  • new remove operator

the remove operator works in a way similar to the delete operator, but does not call the destructor when operating on objects.  It also returns the value removed.
For example:

 my string $str = remove $hash.key;

This would remove "key" from $hash and return the value removed.

  • new extract operator

The extract operator is identical to the "splice" operator, except the extract operator returns any values removed from the list or string operated on

  • constants may be assigned with any expression that does not have side effects

this includes builtin functions that have been tagged as safe to use in constant expressions

  • fixed the ',' operator's precedence in the parser

previously the comma operator's precedence was set far too high which caused problems in certain expressions, for example:

func(1, $a = 2, 3)

would previously be interpreted like this:

func(1, ($a = 2, 3))

contrary to what any reasonable programmer would expect.  From this version on, the comma operator's precedence has been adjusted to be like other programming languages.

  • fixed conversion of characters quoted with '\' in JSON strings

  • changed output of printf format specifiers %n and %N

double quotes (") and '\' characters are now quoted with '\' in strings

  • new warning: non-existent-method-call

raised when a given method name cannot be found in the current class or base classes.  such calls may be valid if the method itself is called from a derived class where the method exists

  • new warning: invalid-operation

warns when an expression will produce a constant output due to type errors

  • new warning: call-with-type-errors

warns when a variant tagged with RT_NOOP is resolved at parse time

  • new warning: return-value-ignored

warns when a function or method that only returns a value and has no side effects has its return value ignored

  • new warning: deprecated

warns when deprecated features are accessed

  • new warning: excess-args

warns when excess arguments are passed to a variant that does not access the excess arguments

  • new warning: duplicate-hash-key

warns when a duplicate hash key is given in an immediate literal hash

  • default warning mask updated

the default warning mask includes: unknown-warning, unreachable-code, nonexistent-method-call, invalid-operation, call-with-type-errors, return-value-ignored, duplicate-hash-key

  • new parse option PO_REQUIRE_TYPES (%require-types), command-line --require-types

if this option is given, then all parameters, return types, and object members must have a declared type
if no return type for functions and methods is explicitly declared when this option is set, then the return type is assumed to be NOTHING
this option also implies PO_STRICT_ARGS

  • new parse option PO_STRICT_ARGS (%strict-args), command-line --strict-args

when this option is set, no variant tagged with RT_NOOP is accessible; any access to variants with this tag at parse-time or at runtime will result in an exception
Additionally, if excess arguments are sent to a function or method that does not access excess arguments, an exception is raised

  • new parse option PO_NO_THREAD_INFO (%no-thread-info), command-line --no-thread-info, domain QDOM_THREAD_INFO

the following functions were tagged with QDOM_THREAD_INFO:

gettid(), num_threads(), thread_list(), get_thread_data(), get_all_thread_data(), getAllThreadCallStacks()

 

  • new parse option PO_NO_EXTERNAL_INFO (%no-external-info), command-line --no-external-info, domain QDOM_EXTERNAL_INFO

the following functions were tagged with QDOM_EXTERNAL_INFO:

getuid(), geteuid(), getgid(), getegid(), getpid(), getppid(), gethostname(),
gethostbyname(), gethostbyaddr(), gethostbyname_long(), gethostbyaddr_long(),
getcwd(), getcwd2(), getpwuid(), getpwuid2(), getpwnam(), getpwnam2()

 

  • new parse option PO_NO_LOCALE_CONTROL (%no-locale-control), command-line --no-locale-control, domain QDOM_LOCALE_CONTROL

the following functions were tagged with QDOM_LOCALE_CONTROL:

TimeZone::set()

 

  • parseDatasource() function updated

parseDatasource() will now parse options at the end of a datasource string in curly brackets ('{' '}') such as the following:
oracle:user/pass@db(al32utf8)%localhost:1521{min=5,max=10}

Any option name can be placed there, whitespace is ignored; options must have the form <key>=<value>

Options are placed in a hash under the "options" key in the value returned from parseDatasource().
The example above would produce the following output:

hash: (8 members)
 type : "oracle"
 user : "user"
 pass : "pass"
 charset : "al32utf8"
 db : "db"
 host : "localhost"
 port : 1521
 options : hash: (2 members)
 min : "5"
 max : "10"

 

Only "min" and "max" options are now currently used - when the DatasourcePool(hash) constructor is used are these options respected if they are present in the hash.

  • new Datasource constructor variant:

Datasource::constructor(hash)

expects a hash as produced by parseDatasource()

  • new DatasourcePool constructor variant:

DatasourcePool::constructor(hash)

expects a hash as produced by parseDatasource()

  • HTTP-CLIENT-RECEIVE-ERROR exception

now returns more information - the exception argument "arg" is a hash with the following keys:
code: the HTTP code received
body: the message body received

  • HAVE_TIMEGM is always true

we no longer use the system function timegm(), so this option (and constant) is always true now
timegm() is now an alias for get_epoch_seconds()

  • new constants

MACHINE_MSB: boolean, True if the machine is a big-endian machine, False if not
Z_DEFAULT_COMPRESSION: integer; the default compression level for zlib

  • module blacklist

qt-core, qt-gui, qt-svn, and qt-opengl are all blacklisted because they were implemented with faulty namespace handling that does not work with qore 0.8.0+; use the 'qt4' module based on libsmoke instead; it's much more complete and supports types, etc

  • COMPATIBILITY WARNING: HTTPClient::setSecure(bool $b = True)

before calling this method without an argument would turn off secure connections, which was counter-intuitive

  • COMPATIBILITY WARNING: HTTPClient::setProxySecure(bool $b = True)

before calling this method without an argument would turn off secure connections, which was counter-intuitive

  • COMPATIBILITY WARNING: HTTPClient::setNoDelay(bool $b = True)

before calling this method without an argument would turn off TCP_NODELAY, which was counter-intuitive

  • COMPATIBILITY WARNING: Socket::setNoDelay(bool $b = True)

before calling this method without an argument would turn off TCP_NODELAY, which was counter-intuitive

  • COMPATIBILITY WARNING: method return values updated

Datasource::open(), Datasource::close(), Datasource::commit(), Datasource::rollback(), DatasourcePool::commit(), DatasourcePool::rollback(), 
FtpClient::connect(), FtpClient::disconnect(), FtpClient::cwd(), FtpClient::get(), FtpClient::put(), FtpClient::del(), Socket::shutdownSSL()

no longer return any value.  In previous versions they would return integer 0.  However, they always throw an exception if there is an error, so any return value was meaningless.