On Saturday, 29 April 2017 at 00:54:59 UTC, Nicholas Wilson wrote:
On Friday, 28 April 2017 at 13:31:33 UTC, Petar Kirov [ZombineDev] wrote:
Other applications include:
* compiling/transpiling D functions to targets
like JS, SPIR-V,

I got you covered ;)

I know, and I'm looking forward to using your GPU support in LDC :P

(LDC not CTFE though. It would be fiendishly complicated to do at CTFE as a fair amount of compiler magic is necessary.)

The way I see it, metaprogramming is a whole spectrum. Yes, you
need a full compiler if you want to compile a whole program to
e.g. JS or WebAsm, but there are many areas where even the smallest
improvement would be highly beneficial.

Take for example C#. It has zero CTFE capabilities (you can
safely ignore constant folding, which works only with string and number literals), yet it has pretty powerful reflection and code-generation capabilities at run-time. Even though the performance difference between CT and RT reflection is orders of magnitude, those reflection capabilities are used pervasively throughout the whole ecosystem. The prime example being LINQ - probably the most widely used feature of .NET. Given a chain of operations
(similar to D's ranges) like:

dbContext.Persons
  .Where(p => p.Birthdate < DateTime.Now.Date.AddYears(-18))
  .Where(p => p.Birthdate > DateTime.Now.Date.AddYears(-28))
.Select(p => new { Name = p.FirstName + " " + p.LastName, Birthdate = p.Birthdate })

It gets compiled to the following SQL:
-- Region Parameters
DECLARE @p0 DateTime = '1989-05-01 00:00:00.000'
DECLARE @p1 DateTime = '1999-05-01 00:00:00.000'
DECLARE @p2 NVarChar(1000) = ' '
-- EndRegion
SELECT ([t0].[FirstName] + @p2) + [t0].[LastName] AS [Name], [t0].[Birthdate]
FROM [Person] AS [t0]
WHERE ([t0].[Birthdate] > @p0) AND ([t0].[Birthdate] < @p1)

As you can see the mapping and filtering is done entirely on the
database server side. The only magic need is to make the compiler to
dump the AST. In C# that's accomplished by wrapping the function
type F in to an Expression<F> [0]. For example C#'s analog of:

InputRange!T filter(T)(InputRange!T source, bool delegate(T) predicate)

is expressed as:

IEnumerable<T> Where<T>(IEnumerable<T> source, Func<T, bool> predicate)

In order to request the AST of the predicate function, it needs to
be wrapped in Expression<T>:

IQueryable<T> Where<T>(
    IQueryable<T> source, Expression<Func<T, bool>> predicate)

(IQueryable<T> [1] is an extension of IEnumerable<T> [2] interface (which is similar to D's Input/ForwardRange-s) which adds the Expression property which represents the AST of the query against the IQueryable data source.)

----

In addition to compiling range operations to database queries, this would also be useful specializing on lambda's in range libraries (see [3]) and
much more.


[0]: https://msdn.microsoft.com/en-us/library/bb335710(v=vs.110).aspx [1]: https://msdn.microsoft.com/en-us/library/bb351562(v=vs.110).aspx [2]: https://msdn.microsoft.com/en-us/library/9eekhta0(v=vs.110).aspx
[3]: https://github.com/dlang/phobos/pull/4265

Reply via email to