On 2016-09-11 14:04, Jay Hammond wrote:
> On 11/09/2016 08:26, btiffin wrote:
>> I'd appreciate any and all feedback on a potential procedure to 
>> provide
>> an eval() powers in Unicon.
>> 
>> Current first cut trial is using Task load() and on the fly 
>> compilation.
>> 
>> Reflective properties will allow for pushing and pulling variables,
>> results of last expression can be returned (suspended?) and passed
>> through to the Task co-expression activation.
>> 
>> I'm still too new to know if this is a sane plan.  Details at
>> https://sourceforge.net/p/unicon/discussion/contributions/thread/6e3bef75/
>> 
>> Any and all opinions appreciated.
>> 
>> Have good, make well,
>> Brian
>> 
>> ------------------------------------------------------------------------------
>> _______________________________________________
>> Unicon-group mailing list
>> Unicon-group@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/unicon-group
> 
> Was the code below,  the sort of thing you were thinking of? I don't
> understand it, so I may be misleading.
> If it is useful,  please feel free to post this thought to the group.
> The file is called ie.icn, and it was a unicon source file (in the
> distribution I guess)  and my copy is dated 2015
> 
> best wishes, Jay
> 
> 
> 

ie.icn code listing snipped...



Thanks, Jay,

Nope (and Yep).  I use ie all the time; as a matter of fact, it got a 
little facelift with my local copy to allow command line recall with GNU 
readline.  See 
http://peoplecards.ca/unicon/programs.html#ie-modified-for-readline for 
some details.  Very similar end-game though.  ie runs code as a separate 
executable, the plan for uval is to load code into the multi-tasker.

I'm planning on code like this:

#
# uval.icn, an eval function
#
# Author: Brian Tiffin
# Dedicated to the public domain
#
# Date: September 2016
# Modified: 2016-09-11/07:28-0400
#
$define base "/tmp/child-xyzzy"

link ximage

#
# try an evaluation
#
global cache
procedure main()
     cache := table()
     program := "# temporary file for eval\n_
         global var\n_
         procedure main()\n_
             var := 5\n_
             suspend ![1,2,3] do var +:= 5\n_
         end"

     while e := eval(program) do {
         v := variable("var", cache[program])
         write("child var: ", v, " e: ", ximage(e))
     }

     # ISSUE HERE, can't refresh the task space: ^cache[program]

     # test cache
     v := &null
     e := eval(program)
     v := variable("var", cache[program])
     write("child var: ", v)
     write("e: ", ximage(e))

end

#
# eval, given string (either code or filename with isfile)
#
procedure eval(s, isfile)
     local f, code, status, child, result

     if \isfile then {
         f := open(s, "r") | fail
         code ||:= every(!read(f))
     } else code := s

     # if cached, just refresh the co-expression
     # otherwise, compile and load the code
     if member(cache, code) then write("^cache[code]")
     else {
         codefile := open(base || ".icn", "w") | fail
         write(codefile, code)
         close(codefile)

         status := system("unicon -s -o " || base  || " " ||
                          base || ".icn 2>/dev/null")
         if \status then
             cache[code] := load(base)
     }

     # if there is code, activate the co-expression
     if \cache[code] then result := @cache[code]

     remove(base || ".icn")
     remove(base)

     return \result | fail
end


That version is pretty close, but it seems refreshing a Task (to avoid 
recompiling code over and over again, once in a cache) fails with an

Attempt to refresh main

For now, it means no working cache, and stays a little more expensive.  
eval() might return the co-expression, but it seems more useful if it 
produces the value returned from the code itself.  And the cache index 
might be better as a hash or some such, instead of the raw code string.

See http://peoplecards.ca/unicon/programs.html#eval for ongoing 
experiments.

Access to (global) variables is working, any type of result works (all 
due to the power of co-expressions, and the multi-tasker) suspension 
works (need to figure out when a code reset should occur), but there 
needs to be a way of resetting the co-expression, or unloading the Task, 
for this to be something practical and not a resource gobbler.

For one-off expressions, or one pass generators, it works well already.  
And feels like a built in eval().  The boilerplate "procedure main" etc, 
will be factored out for the next trial, and the string won't need to 
include that.  For filenames passed to eval with isfile set, the source 
would still need to be complete, but string code will look more like 
expressions from a user perspective.

I'll keep the trials and tribulations in the UP document at 
http://peoplecards.ca/unicon/programs.html#eval and that entry will 
expand with -v1 -v2 ... -final code attempts so that readers can see how 
the experiments progressed.  Still much to learn.

Clinton has already piped in that he'd like to see this effort succeed, 
so there may be some internal enhancements to Task powers to make this 
work as it should.  It's nice knowing that the compiler writers are 
willing to help out with low level code.  Unicon for the win!

Caveat: for now, even if it goes to plan, it'll be an expensive 
operation, calling the compiler to get things setup. And being an eval 
sequence, means there has to be some level of trust on the code it 
attempts.  You would not want a public facing web form being the source 
of the code, for instance, without an entire sandbox infrastructure in 
place.

Cheers,
Brian

------------------------------------------------------------------------------
_______________________________________________
Unicon-group mailing list
Unicon-group@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/unicon-group

Reply via email to