lua-users home
lua-l archive

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


On Mon, Jun 12, 2017 at 3:48 AM, Luiz Henrique de Figueiredo
<lhf@tecgraf.puc-rio.br> wrote:
>> This message seems to slightly pre-date my gmail records so I am
>> stealing the title to ask a question. The readme states potential
>> usage includes "Experimenting with new syntax without hacking the Lua
>> source (reserved.lua)".
>>
>> Would this be the mechanism one would utilise to experiment with
>> adding "domain specific languages" to Lua?
>
> I see it as *one* mechanism, yes, and an easy one to use. But there are
> others, such as Metalua. I'd love to hear about uses of ltokenp as a
> tool for building DSLs with Lua.

You are a cruel and heartless man. Have you no thought for those of
use that can't sleep with that kind of temptation just sitting there?
:P

I'd really like to see two things in lua: a native persistence engine
and a linq like syntax for working with tables
(https://msdn.microsoft.com/en-us/library/bb308959.aspx).

I'm playing with the idea of a lua table persistence library based on
lmdb (https://symas.com/lightning-memory-mapped-database/). The lua
wrapper I am using is called lightningmdb and it's brilliant
(https://github.com/shmul/lightningmdb). I had a prototype, then I
broke it, so I started on my first revision,  but just broke that too.
I had it working with moses (kind of) to produce the chained table
manipulation pattern but ltokenp just makes my head spin with ideas
(like wrapping moses!!!!). I can also track the changes made to a
table via some metatable mechanisms borrowed from PIL. Where it gets
really exiting is lmdb can be used for indexing table values. I can
pull data from table values by running an anonymous function during
commits and storing values as a reverse key back to the original data
(instant index!). I had an index working in a prototype that wasn't
very dynamic, but the pattern was there.

The following is a non-working snippet pulled from a test file without
indexes. The commit() doesn't work with moses yet, but I think it
gives the idea. Wouldn't all this look really nice with a custom DSL
like Steve Donavan did in Penlight?

--load the library
local persist = require("lua-persist")
--open the file
local env = persist.new("data")
--open your database/table
local db_players = env:open_database("players")

local serpent = require("serpent")
local m = require("moses")

local function getPlayerYears(k,v,p)
  --  if type(k) ~= 'number' then
  --    return nil
  --  end
  --print(k)
  if(string.sub(k,1,4) == tostring(p)) then
    return string.sub(k,5),{k,v,p}
  end
end


local function getPlayersByCity(k,v,...)
  local p = table.pack(...)
  local ok,res
  if type(v) == 'string' then
    ok, res = assert(serpent.load(v))
  elseif type(v) == 'table' then
    ok, res = true, v
  else
    return nil
  end

  if ok then
    for _,v in pairs(p) do
      if res.Team.City == v then
        return k,res
      end
    end
  end
  return nil
end


--This was my own pattern
local retvals = db_players:search(getPlayersByCity,"Vancouver")

local players = db_players:get_all()

--This is using moses
local van = m.chain(players)
  :select(getPlayersByCity,"Vancouver","Detroit")
  :countBy(function(i,v) return v.Team.City end)
  :value()

--local teams = m.chain(players):countBy(function(i,v) return
v.Team.City end):value()

if teams then
  for i,v in pairs(teams) do
    print(i,v)
  end
else
  print('no vals')
end

--Sadly the commit at the end doesn't work...
m.chain(players)
  :select(function(i,v) return v.Team.City=="Vancouver" end)
  :forEach(function(i,v) v.Team.Name="Nuckleheads" end)
  :commit()

env:close()


Night,
Russ