lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Fri, Apr 28, 2017 at 4:36 PM, Jay Carlson <nop@nop.com> wrote:
> [Is there a comprehensive list somewhere of all the big ways to build DSLs in Lua?]
>
> On Apr 27, 2017, at 3:00 PM, Russell Haley <russ.haley@gmail.com> wrote:
>>>
>> I was just contemplating how one would add a linq like feature to Lua
>> for searching and returning result sets as tables without having to
>> write iterators. This syntax would solve that problem quite nicely,
>> wouldn't it? However, would that mean the need to add other functions
>> like where(), join() and similar 'SQL like' concepts?
>
> For any programming language people who aren't familiar with it, here's the outer language's syntactic view of LINQ:
>
> LINQ is a way of writing a kind of AST literal, parsed from a specific query sub-language.
>
> The query sublanguage is itself interesting. At runtime, the AST can be executed directly, compiled to bytecode, or unparsed into SQL queries (for example). But what I am especially interested in for Lua are meta-mechanisms, the things that can support multiple little languages. LINQ is a good instance of something it would be nice to be able to implement, then.[1]
>
> One solution is to create your language out of function calls, tables, operators, and values, in the way the native LPeg does. As I've complained ad tedium, there is still no good way to create new control mechanisms this way except through lambdas or Smalltalk/Ruby-style blocks; both postpone evaluation of code in the current scope. But maybe you don't need those control mechanisms very much. And even if you do need lambdas, lexical scoping always works the right way.
>
> Deserving special mention for constructing DSLs are common syntax hacks, like chaining methods, abusing "f 'name' {}", etc.
>
> Another is macros, sometimes just to augment the previous approach just enough. I have convinced myself that there will never be execution at compile-time in Lua (and also convinced myself that it is a good judgement for Lua). Sorta in the same category are various other meta-Luas. The cost is direct source compatibility.[2]
>
> My favorite method (but alas the one I use least) is to parse a string at runtime and turn it into a Lua function. So taking the Wikipedia LINQ C# example, it would look something like:
>
> results =  linq[[
>   from c in SomeCollection
>   where c.SomeProperty < 10
>   select new {c.SomeProperty, c.OtherProperty} ]]
>
> for result in ipairs(results) do
>   print(result)
> end
>
> Conveniently for me, there are no unbound variables in that query. Because otherwise I'd have to write something like:
>
> results = linq{[[
>   from c in SomeCollection
>   where c.SomeProperty < limit
>   select new {c.SomeProperty, c.OtherProperty} ]],
>   limit=limit}
>
> Note that the stuff in linq[[ ]]'s function can't write to any variables in the outer scope.[3] It can write on objects it's passed, though.

I believe Ronald has provided the functional implementation to those
imagined keyword mappings in his Moses library (another post)?
http://yonaba.github.io/Moses/doc/

His chaining seems to be a "syntax hack you mentioned" but in .net
there is a similar syntax to access LINQ without the DSL.

Russ