Skip to content

0.9.4

Compare
Choose a tag to compare
@dhil dhil released this 01 Sep 18:12
· 120 commits to master since this release
86978b4

CHANGES:

Queries mixing set and bag semantics

Links now provides experimental support for SQL queries mixing set and bag semantics.

When the mixing_norm=on flag is added to the configuration file, or when a query is defined in a query mixing { ... } block, Links will use a new query evaluator, allowing the programmer to call deduplication functions (dedup and distinct) within database queries. These are handled with set-based SQL statements select distinct / union, in addition to the usual bag-based select / union all.

# will run on the DB as "select distinct e.dept as dept from employees"
query mixing {
  dedup(for (e <-- employees) [(dept = e.dept)])
}

Queries mixing set and bag semantics may, in some cases, require the use of the SQL:1999 keyword lateral; Links implements an optional query transformation to produce queries that do not use lateral (allowing the use of older DBMSs): this behaviour is enabled by using query delat in place of query mixing.

Further information on this feature is provided in the Links GitHub wiki.

DateTime type

Links now includes a primitive type, DateTime, for dates and times.
This is a breaking change from previous versions, where dateToInt
and intToDate operated on a record.

The primitive type allows us to better timezones, and also allows us
to work seamlessly with timestamps in the database.

Obtain a DateTime via:

  • the now() function to get a timestamp for the current local time
  • Using parseDate on an ISO-formatted string (e.g., parseDate("26-07-2021 14:26:00+1"))
  • A DateTime field in the database
  • intToDate(X) where X is a UNIX timestamp
  • beginningOfTime and forever, which are special timestamps guaranteed to be less than (resp. greater than) all other timestamps

Project fields out of the type:

  • utcYear, utcMonth, utcDay, utcHours, utcMinutes, utcSeconds, utcMilliseconds projects the given field in the UTC time zone
  • localYear, localMonth, localDay, localHours, localMinutes, localSeconds, localMilliseconds projects the given field in the local time zone
  • dateYear, dateMonth, dateDay, dateHours, dateMinutes, dateSeconds, dateMilliseconds projects the given field in a given timezone (e.g., to project the hours field of a DateTime dt in BST, one would write dateHours(dt, 1), where 1 is the timezone offset.

You can also print out the DateTime using show (which is an alias of
showLocal) and showUTC.

DateTimes are comparable as normal.

Due to limitations of the underlying library, the minimum timezone granularity is one hour. Unfortunately, this means we can't handle Indian timezones, for example.

New surface syntax

Presence type arguments

Breaking change: New syntax has been added to support type arguments of kind Presence. Here are some example of the syntax:

typename T(p::Presence) = (foo{p});

(foo=4200) : T({:Int})         # Present with type Int
()         : T({-})            # Absent
(foo=4200) : T({%})            # Unnamed flexible variable
(foo=true) : T({%p})           # Named flexible variable
fun(r : T({_})) { () }         # Anonymous presence variable
fun(r : T({p})) { r : T({p}) } # Named presence variable

The syntactic sugar for effect and record fields which lets one omit the () has been removed in order to resolve the otherwise ambiguity between the presence type argument {wild} from the row type argument {wild}. Note however that it is still possible to omit the () for variant fields.

Mono restriction

It is now possible to annotate type variables with Mono restriction, e.g. sig id : (a::(Any,Mono)) -> a::(Any,Mono).

Recursive rows

  • Effect variables can be recursive, e.g. { |(mu a.F:(() { |a}-> ()) {}-> b|c)}.
  • Breaking change: Recursive rows are no longer restricted to variant syntax, i.e. separating fields using |. Recursive record and effects rows separate fields using , now.
  • Recursive variants with no directly exposed fields no longer require the vertical bar separating fields from the row variable, e.g. [|(mu a. Foo)|] is equivalent to [| |(mu a . Foo)|].

Roundtrip: New pretty printer for types

This version of Links introduces a new pretty printer for types, called Roundtrip. This fixes various round-tripping issues.

The Roundtrip printer is now active by default. The old printer is still present.

The printer(s) to be used can be selected using the setting types_pretty_printer_engine, with the following values:

  • roundtrip: the new printer
  • old: the original printer
  • derived: no pretty printing - prints the OCaml representation of the types

Note that one can select multiple printers at once, for comparison; this is done by separating printer names by commas, e.g.:

@set types_pretty_printer_engine "roundtrip,old";

Effect Syntactic Sugar

This version implements enhanced syntactic sugar for effects. The changes influence both the Roundtrip printer (see above) and the desugaring passes (between parsing and typechecking).

(Note: Most of effect sugar, and in particular the changes introduced in this version, requires the effect_sugar setting to be true.)

There is a new setting effect_sugar_policy which allows one to set which components of effect sugar to use. The available options (with shortcuts for convencience) are:

  • presence_omit [shotcut pres]: omit presence polymorphic operations within effect rows
  • alias_omit [shortcut alias]: hide empty (and emptied using pres) shared effect rows in the last argument of aliases
  • arrows_show_implicit_effect_variable [shortcut show_implicit]: display the imlicit shared effect on arrows
  • arrows_curried_hide_fresh [shortcut chf]: in curried functions, argument collection arrows are assumed to have fresh effects and these are hidden
  • contract_operation_arrows [shortcut contract]: contract operation arrows: E:() {}-> a to E:a and E:(a) {}-> b to E:(a) -> b
  • open_default [shortcut open]: effect rows are open by default, closed with syntax { | .}
  • final_arrow_shares_with_alias [shortcut final_arrow]: final arrow and a following type alias may share implicit effects
  • all_implicit_arrows_share [shortcut all_arrows]: all arrows with implicit effect vars will be unified, an experimental setting

Multiple of these can be selected, separated by commas, e.g.:

@set effect_sugar_policy "pres,alias,contract";

A version of the above is also available by entering @help effect_sugar_policy; in Links.

These changes are explained in more depth and with examples in Links GitHub Wiki/Effect Sugar.

Other fixes / Miscellaneous

  • Relational lenses are now enabled by default.
  • Fixed a bug where the REPL would unconditionally print a stacktrace for unknown directives.
  • Fixed a bug where deeply nested JSON literals would cause the client to stack overflow.
  • Fixed a bug where big server side values would cause the client to stack overflow.
  • Fixed JavaScript compilation of top-level anonymous functions.
  • Fixed a bug where the server would inadvertently respond with response 500 following the (successful) termination of a server side process.
  • The body of an escape expression has been made more permissive (grammatically) as it can now be any expression.