<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000066">
    This may come close:<br>
    <br>
    <a class="moz-txt-link-freetext" href="https://github.com/Eonblast/luerl/tree/henning">https://github.com/Eonblast/luerl/tree/henning</a><br>
    <br>
    For the criticism I still have, see inline comments please.<br>
    <br>
    <br>
    On 2/24/12 12:19 AM, Robert Virding wrote:
    <blockquote cite="mid:9968cdcb-0ccf-4992-a356-3bec3573d843@knuth"
      type="cite">
      <style type="text/css">p { margin: 0; }</style>
      <div style="font-family: Times New Roman; font-size: 12pt; color:
        rgb(0, 0, 0);">Hi Henning,<br>
        <br>
        Ok we will go towards making them more Lua-C like. But we are
        running in an Erlang environment so they will handle errors in
        an Erlangy way:<br>
        <br>
        - The 'eval' functions will catch errors and return {ok,Result}
        | {error,Reason}.<br>
      </div>
    </blockquote>
    What this gives away is the chance of less cluttered code, to use
    eval 'in-line' with no pattern matching result extraction, if so
    wanted.<br>
    <blockquote cite="mid:9968cdcb-0ccf-4992-a356-3bec3573d843@knuth"
      type="cite">
      <div style="font-family: Times New Roman; font-size: 12pt; color:
        rgb(0, 0, 0);">- The 'do' and 'call' functions will not catch
        errors and return {Result,NewState}. Errors caught in the Lua
        code, with 'pcall' which does not exist yet, will of course not
        generate an error at the Erlang interface.<br>
      </div>
    </blockquote>
    <br>
    Isn't the chance to look at the soon to be discarded stack something
    that needs the support of giving over a suitable callback. And thus
    offer pcall from Erlang?<br>
    <br>
    <blockquote cite="mid:9968cdcb-0ccf-4992-a356-3bec3573d843@knuth"
      type="cite">
      <div style="font-family: Times New Roman; font-size: 12pt; color:
        rgb(0, 0, 0);">- We will initialise/cleanup the state with
        'start'/'stop' in an Erlangy way.<br>
        - We will 'encode'/'decode' Lua data.<br>
        - And we will both 'load' and 'compile' Lua and
        load/compile(String) -> {ok,Form} | {error,Reason}.<br>
      </div>
    </blockquote>
    I did all those changes, and see /examples/hello/hello2.erl. The
    interface comes across as bloated like this. I think.<br>
    <br>
    Best,<br>
    Henning<br>
    <br>
    <blockquote cite="mid:9968cdcb-0ccf-4992-a356-3bec3573d843@knuth"
      type="cite">
      <div style="font-family: Times New Roman; font-size: 12pt; color:
        #000000">The erlang format of errors from the luerl runtime will
        be something {luerl_error,Error} where will be something like
        {badarg,sub,Args}. I will try to give them similar names as in
        Lua. Erlang errors are very seldom string values, in some cases
        there are format_error/1 functions which return string values.
        This will also make it easy to see which are Lua errors and
        which are from the Erlang code.<br>
        <br>
        Robert<br>
        <br>
        <hr id="zwchr">
        <blockquote style="border-left:2px solid rgb(16, 16,
255);margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;">
          <font face="Calibri">Hi Robert,<br>
            <br>
            Thanks for the feedback. Yes, it's a matter of viewpoint,
            from Erlang or Lua. <br>
            <br>
            If you feel the audience for Luerl would be people who did
            work with Lua before, many of them would know the C
            interface and thus, it could be helpful for them to stick to
            these names. <br>
            <br>
            Since I work with Lua, embedded Lua and Erlang, I would
            treasure consistency between the C and Erlang underside of
            Lua.<br>
            <br>
            Lua is so much for embedding that the C interface functions
            are actually listed in the manual earlier than the language
            functions (or at least once it was so).<br>
            <br>
            I'll agree that 'load' is not intuitively right. But it
            would increase consistency.<br>
            <br>
            'dofile' is a staple of Lua proper, also exists in the C
            interface and again would probably be what somebody coming
            from Lua would look for, so would be --- nice to have in my
            view. 'evalfile' exists for symmetry.<br>
            <br>
            As I wrote, my interface proposal is bloated, but the
            differences between 'do' and 'call' would be that 'call'
            only takes pre-compiled chunks and crashes with anything
            else. While "do" is more careless and can be fed anything:
            Lua code in Strings, Binaries, or pre-compiled chunks.<br>
            <br>
            "eval" - for easiest use, in place, returns pure Result<br>
            "do" - same as eval but returns Result and State*<br>
            "call" - takes only precompiled chunks, returns </font><font
            face="Calibri">Result and State</font><br>
          <font face="Calibri"><br>
            * </font><font face="Calibri">(in Erlang, you can't just <i>not</i>
            fetch the second return value, as is possible in Lua)<br>
            <br>
            My two cents on: "encode" and "decode" I find them better
            but still not perfect. It's really again the perspective
            from Erlang. "wrap"/ "unwrap"? "stage"/"unstage"? (Looks
            like no difference to "encode" at first sight -- but I do
            think there is one.)<br>
            <br>
            As for error handling: I came to think that a try-catch wrap
            in eval as standard service would be nice. So using eval
            you'd be sure it will always return, of with an error
            message. While that may in fact be too much Lua thinking,
            and too alien to Erlang, it's what comes to mind for how I
            would like "eval" to be a carefree, fast thing to use. </font><font
            face="Calibri">(Erlang has a "let it crash" philosophy where
            errors are usually handled but a process automatically
            restarted.)<br>
          </font><br>
          <font face="Calibri"> The whole point of "pcall" is to be a
            protected version of "call". Using "pcall" in Lua/C
            interface one can be sure that errors don't crash the
            program and can be handled. Specifically by a handler
            function which has access to the state before the stack is
            discarded. <br>
            <br>
            I think it may make sense to treat errors that originate in
            Lua (or even in the Luerl VM itself, while in development)
            differently from errors that originate in the Erlang source.
            <br>
          </font>  <br>
          Best,<br>
          Henning<br>
          <br>
          <div class="moz-signature">-- <br>
            <div style="font-family:Calibri, Verdana, Arial, sans-serif">
              <span style="color:navy;"><b>Henning Diedrich</b><br>
                CEO<br>
              </span> <br>
              <table border="0" cellpadding="0" cellspacing="0">
                <tbody>
                  <tr>
                    <td valign="top"> <img
                        src="cid:part1.07000103.02060002@eonblast.com"
                        alt="" style="margin-bottom:5px"><br>
                    </td>
                    <td width="10px"><br>
                    </td>
                    <td valign="top"><span
                        style="font-size:9.0pt;color:gray"> Eonblast
                        Corporation<br>
                        <a moz-do-not-send="true"
                          class="moz-txt-link-abbreviated"
                          href="mailto:hdiedrich@eonblast.com"
                          target="_blank">hdiedrich@eonblast.com</a><br>
                        +1.404.418.5002 w<br>
                        <a moz-do-not-send="true"
                          class="moz-txt-link-abbreviated"
                          href="http://www.eonblast.com" target="_blank">www.eonblast.com</a></span>
                    </td>
                  </tr>
                </tbody>
              </table>
              <br>
              <small>This email contains confidential and/or privileged
                information. If you are not the intended recipient (or
                have received this email in error) please notify the
                sender immediately and destroy this email. Any
                unauthorized copying, disclosure or distribution of the
                material in this email is prohibited.</small> </div>
          </div>
          <br>
          <br>
          On 2/22/12 3:04 AM, Robert Virding wrote:
          <blockquote
            cite="mid:aeb64036-52d8-45a0-a0c5-1f736b497d14@knuth">
            <style>p { margin: 0; }</style>
            <div style="font-family: Times New Roman; font-size: 12pt;
              color: #000000"><font size="3">Hi,<br>
                <br>
              </font><font size="3">Most of the difference is just in
                terminology and from which side you view it, from erlang
                or Lua. For example, for me loading means actually
                getting it into the sytem not just compiling it into a
                runnable form. And I view these functions from the
                erlang side. I will also admit that I am a bit hazy as
                to how the C-side functions work, it seems easier within
                the language.<br>
                <br>
                'eval' and 'do' work well for me, though I do wonder if
                we need 'evalfile' and 'dofile'. I prefer 'compile'
                instead of 'load' as this is what is does. 'call' is
                fine. What is the difference between 'call' and 'do'?
                For creating and destroying state I would prefer either
                'new' / 'delete' or 'start' / 'stop' depending on
                whether you want to view the state as just data or as
                some form of concurrent activity, a separate process in
                Erlang.<br>
                <br>
                I would use 'encode' / 'decode' for converting between
                an Erlang representation and an internal luerl
                representation. So:<br>
                <br>
                luerl:encode(Erlang, State) -> {Luerl,State}.<br>
                luerl:decode(Luerl, State) -> Erlang.</font><br>
              <br>
              <div style="text-align: left;">Encoding will modify the
                state as tables only exist within that state. If it not
                done this way then there is no need of these functions
                as the representation is the same and this conversion
                will be done in the other interface functions. So for
                example a Lua strings are Erlang binaries and tables
                will are a list of tuple pairs,<br>
                <br>
                Lua {['a']=97,['b']=98,10,20,30} <==> Erlang
[{1.0,10.0},{2.0,20.0},{3.0,30.0},{<<"a">>,97.0},{<<"b">>,98.0}]<br>
                <br>
                Putting Lua tables into the state is also the only way
                to handle the difference in the meaning of equality
                between Lua and Erlang.<br>
                <br>
                For errors I have been thinking in the Erlang way. The
                only function to actually return an error value would be
                'compile' (or 'load') which would become<br>
                <br>
                luerl:compile(String) -> {ok,Chunk} | {error,Reason}.<br>
                <br>
                All errors during the Lua execution, unless they are
                caught internally, would result in Erlang exceptions
                which would handled in the normal Erlang way, either by
                catching it or having the Erlang process die.<br>
                <br>
                The result returned from Lua and the arguments to a call
                would be a list of Erlang values. If no values are
                returned the list is empty otherwise it would contain
                same number of elements as in the 'return' statement.<br>
                <br>
                Those are my thoughts for the moment. Now I will go back
                and try and code the idiosyncrasies of string.sub.<br>
                <br>
                Robert <br>
              </div>
              <br>
              <hr id="zwchr">
              <blockquote style="border-left:2px solid rgb(16, 16,
255);margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;">
                Hi Robert,<br>
                <br>
                To allow for String|Chunk, the chunks returned from ps/1
                would have to be wrapped to be distinguishable from the
                Strings. I think 'functiondef' could be the right
                choice.<br>
                <br>
                For the names, I'd propose to maybe stay closer to the
                Lua language function names and its C interface [1]. <br>
                <br>
                But at any rate, to maybe decide for one of "do" and
                "eval" to 1) return bare results 2) return {Result,
                State}. Rather than making this dependent on whether
                State was handed in or not as a parameter?<br>
                <br>
                Since Lua uses dofile() both in the Lua language and the
                C interface, (and since of course neither case returns
                state), the "do" functions look earmarked for returning
                the simple, bare bones Result. However ... somehow
                "eval" is a better fit for a function that is expected
                to return something.<br>
                <br>
                Lua's C interface uses "load" for parsing-only: load,
                loadfile, lua_load [2], lua_loadfile, lua_loadstring,
                lua_loadbuffer.<br>
                <br>
                This could be an alternative to wrapping the chunks: for
                load, in Lua <i>"the string mode controls whether the
                  chunk can be text or binary (that is, a precompiled
                  chunk). It may be the string "b" (only binary chunks),
                  "t" (only text chunks), or "bt" (both binary and
                  text). The default is "bt". </i>[5]<br>
                <br>
                The type that the loads return is 'function': <i>"If
                  there are no syntactic errors, returns the compiled
                  chunk as a function; otherwise, returns nil plus the
                  error message." --- </i>therefore, the right chunk
                wrapper could be { functiondef, ... }, instead of
                compiled chunks being lists as outermost type.<br>
                <br>
                Execution of pre-parsed/compiled chunks is "call":
                pcall, xpcall, lua_call, lua_pcall [3],  and lua_pcallk.
                <br>
                <br>
                State is created and destroyed by lua_newstate and
                lua_close.<br>
                <br>
                There is no "eval" in Lua. <br>
                <br>
                So here's my proposal:<br>
                <br>
                luerl:eval(String|Chunk[, State]) -> Result.<br>
                luerl:evalfile(PathString[, State]) -> Result.<br>
                <br>
                luerl:do(String|Chunk[, State]) -> {Result,
                NewState}.<br>
                luerl:dofile(PathString[, State]) -> {Result,
                NewState}.<br>
                <br>
                luerl:newstate() -> State.<br>
                luerl:close(State) -> ok.<br>
                <br>
                luerl:load(String) -> {ok, Chunk}.<br>
                luerl:loadfile(PathString) -> {ok, Chunk}.<br>
                luerl:call(Chunk[, State][, ErlParamList()]) ->
                {Result, NewState}.<br>
                <br>
                luerl:tolua(list()) -> LuerlTermsList().<br>
                luerl:toerlang(LuerlTermsList()) -> list().<br>
                <br>
                This would be somewhat in keeping with Lua's naming.<br>
                <br>
                I am unclear about error state returns. Simply in the
                Result I guess?<br>
                <br>
                Relative to your proposal that is:<br>
                luerl:eval(String|Chunk) -> Result. =>
                luerl:eval(String|Chunk[, State]) -> Result.<br>
                luerl:dofile(String) -> Result. =>
                luerl:dofile(PathString[, State]) -> {Result,State}.<br>
                luerl:new() -> State. (currently luerl:init() ->
                State.) =>luerl:newstate() -> State.<br>
                luerl:eval(String|Chunk, State) -> {Result,NewState}.
                => luerl:eval(String|Chunk, State) ->
                {Result,NewState}.
                <div style="text-align: left;">luerl:dofile(String,
                  State) -> {Result,NewState}. => same<br>
                </div>
                luerl:compile(String) -> {ok,Chunk}. =>
                luerl:load(String) -> {ok,Chunk}.<br>
                <br>
                Beyond that, I had thought with 'interface' you would be
                addressing the direct interchange of values between
                Erlang and Lua. I'd be all for making the collection of
                tables in the Lua state accessible and writable,
                directly, somehow navigating into it using a key
                structure. And if possible, vice versa: giving Lua
                direct access to Erlang state.<br>
                <br>
                Best,<br>
                Henning<br>
                <br>
                <br>
                [1] <a moz-do-not-send="true"
                  class="moz-txt-link-freetext"
                  href="http://www.lua.org/manual/5.2/manual.html#4.8"
                  target="_blank">http://www.lua.org/manual/5.2/manual.html#4.8</a><br>
                <br>
                [2] <i>One note I like, in the description of the C
                  function lua_load : "The source argument gives a name
                  to the chunk, which is used for error messages and in
                  debug information (see §4.9)." </i><a
                  moz-do-not-send="true" class="moz-txt-link-freetext"
                  href="http://www.lua.org/manual/5.2/manual.html#lua_load"
                  target="_blank">http://www.lua.org/manual/5.2/manual.html#lua_load</a>
                - <a moz-do-not-send="true"
                  class="moz-txt-link-freetext"
                  href="http://www.lua.org/manual/5.2/manual.html#2.3"
                  target="_blank">http://www.lua.org/manual/5.2/manual.html#2.3</a><br>
                <br>
                [3] <i>When you use xpcall or lua_pcall, you may give a
                  message handler to be called in case of errors. This
                  function is called with the original error message and
                  returns a new error message. It is called before the
                  error unwinds the stack, so that it can gather more
                  information about the error, for instance by
                  inspecting the stack and creating a stack traceback.
                  This message handler is still protected by the
                  protected call; so, an error inside the message
                  handler will call the message handler again. If this
                  loop goes on, Lua breaks it and returns an appropriate
                  message.</i> - <br>
                <a moz-do-not-send="true" class="moz-txt-link-freetext"
                  href="http://www.lua.org/manual/5.2/manual.html#2.3"
                  target="_blank">http://www.lua.org/manual/5.2/manual.html#2.3</a><br>
                <br>
                [4] In Lua (not the C interface), dofile does not run in
                protected mode. <a moz-do-not-send="true"
                  class="moz-txt-link-freetext"
                  href="http://www.lua.org/manual/5.2/manual.html#6.1"
                  target="_blank">http://www.lua.org/manual/5.2/manual.html#6.1</a><br>
                <br>
                [5] <a moz-do-not-send="true"
                  class="moz-txt-link-freetext"
                  href="http://www.lua.org/manual/5.2/manual.html#6.1"
                  target="_blank">http://www.lua.org/manual/5.2/manual.html#6.1</a><br>
                <br>
                <br>
                <br>
                On 2/20/12 10:59 PM, Robert Virding wrote:<br>
                <blockquote
                  cite="mid:a6f24fc1-9075-4a31-bebd-5bc8812ac444@knuth">
                  <div style="font-family: Times New Roman; font-size:
                    12pt; color: #000000">[snip] I had planned something
                    along the lines of:<br>
                    <br>
                    luerl:eval(String|Chunk) -> Result.<br>
                    luerl:dofile(String) -> Result.<br>
                    <br>
                    Basic simple interface which initialises a state and
                    evaluates the chunk String in it returning a list of
                    return values (if any). For example luer:eval("local
                    t={'a','b'} return t[1],t[2]") will return
                    [<<"a">>,<<"b">>].
                    luerl:dofile/1 is not really necessary.<br>
                    <br>
                    luerl:new() -> State.<br>
                    luerl:eval(String|Chunk, State) ->
                    {Result,NewState}.<br>
                    <div style="text-align: left;">luerl:dofile(String,
                      State) -> {Result,NewState}.<br>
                    </div>
                    luerl:compile(String) -> {ok,Chunk}.<br>
                    <br>
                    A more complex interface. luerl:new/0 creates an
                    initial state. luerl:eval/2 will evaluate a chunk in
                    a state and return the values and the updated state.
                    This state can be reused to evaluate new chunks.
                    Again luerl:dofile/2 is not really necessary.
                    luerl:compile(String) compiles the string into an
                    internal form ready to run in eval/1/2.<br>
                    <br>
                    Result is always a list of return values which may
                    be empty if the chunk does not do a return with
                    values. For data types:<br>
                    <br>
                    Lua strings are binaries<br>
                    Lua numbers are floats<br>
                    Lua tables are orddicts (property lists) of
                    key-value tuples<br>
                    Lua true, false, nil are just the atoms true, false,
                    nil<br>
                    <br>
                    Anyway something along those lines. It might be nice
                    to have a function call wrapper which would allow
                    you a more erlang like way of calling a luerl
                    function.<br>
                    <br>
                    Robert<br>
                    <br>
                    <hr id="zwchr">
                    <blockquote style="border-left:2px solid rgb(16, 16,
255);margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;">
                      Regarding interface function names:<br>
                      <br>
                      I wonder what logic Luerl's names of do and eval
                      follow:<br>
                      <br>
                      dofile/1, like eval/1, returns a pragmatic Ret <br>
                      <br>
                      while do/2 returns {String, State}<br>
                      <br>
                      Since you are exporting ps/1, there should maybe
                      be a dochunk/2? <br>
                      <br>
                      And /1, too? <br>
                      <br>
                      Or should it maybe be evalchunk/1, dochunk/2 (the
                      /2s with State as second parameter)?<br>
                      <br>
                      Here are some relevant functions from Lua's C
                      interface.<br>
                      <br>
                      <blockquote><b>luaL_dofile</b><br>
                        <br>
                        [-0, +?, m]<br>
                        int luaL_dofile (lua_State *L, const char
                        *filename);<br>
                        Loads and runs the given file. It is defined as
                        the following macro:<br>
                        <br>
                             (luaL_loadfile(L, filename) || lua_pcall(L,
                        0, LUA_MULTRET, 0))<br>
                        It returns false if there are no errors or true
                        in case of errors.<br>
                        <br>
                        <b>luaL_dostring</b><br>
                        <br>
                        [-0, +?, –]<br>
                        int luaL_dostring (lua_State *L, const char
                        *str);<br>
                        Loads and runs the given string. It is defined
                        as the following macro:<br>
                        <br>
                             (luaL_loadstring(L, str) || lua_pcall(L, 0,
                        LUA_MULTRET, 0))<br>
                        It returns false if there are no errors or true
                        in case of errors.<br>
                        <br>
                        <b>luaL_loadstring</b><br>
                        <br>
                        [-0, +1, –]<br>
                        int luaL_loadstring (lua_State *L, const char
                        *s);<br>
                        Loads a string as a Lua chunk. This function
                        uses lua_load to load the chunk in the
                        zero-terminated string s.<br>
                        <br>
                        This function returns the same results as
                        lua_load.<br>
                        <br>
                        Also as lua_load, this function only loads the
                        chunk; it does not run it.<br>
                        <br>
                        <b>luaL_newstate</b><br>
                        <br>
                        [-0, +0, –]<br>
                        lua_State *luaL_newstate (void);<br>
                        Creates a new Lua state. It calls lua_newstate
                        with an allocator based on the standard C
                        realloc function and then sets a panic function
                        (see §4.6) that prints an error message to the
                        standard error output in case of fatal errors.<br>
                        <br>
                        Returns the new state, or NULL if there is a
                        memory allocation error.<br>
                      </blockquote>
                      <br>
                      Source: <a moz-do-not-send="true"
                        class="moz-txt-link-freetext"
                        href="http://www.lua.org/manual/5.2/manual.html"
                        target="_blank">http://www.lua.org/manual/5.2/manual.html</a><br>
                    </blockquote>
                    <br>
                  </div>
                </blockquote>
                <br>
                <br>
                _______________________________________________<br>
                erlang-questions mailing list<br>
                <a moz-do-not-send="true"
                  class="moz-txt-link-abbreviated"
                  href="mailto:erlang-questions@erlang.org"
                  target="_blank">erlang-questions@erlang.org</a><br>
                <a moz-do-not-send="true" class="moz-txt-link-freetext"
href="http://erlang.org/mailman/listinfo/erlang-questions"
                  target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
              </blockquote>
              <br>
            </div>
          </blockquote>
          <br>
          _______________________________________________<br>
          erlang-questions mailing list<br>
          <a class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
          <a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
        </blockquote>
        <br>
      </div>
    </blockquote>
    <br>
  </body>
</html>