david at viral.academy
Wed Apr 8 05:54:44 EDT 2015
Thanks for this Andrew - I learned a lot. I spend a lot of time passing
messages around Livecode objects with a view to making them standalone code
chunks. Debugging works pretty well - but there was a need for a library
and a graphing mechanism - design pattern style. This all adds overhead I
guess when it comes to just reading code, and the design patterns for
callbacks that closures seem to encourage makes this easier by itself?
One thing that would be good to know more about with regard to Livecode is
the memory handling - so when does a peice of code get released from
memory? My understanding is that it does not - except possibly when the
stack it resides in is "deleted" from memory?
Otherwise my understanding is that like with Hypercard the script is
compiled to bytecode the first time it is executed (which is a relatively
slow step), but thereafter resides in memory to be executed when needed. Is
that about right?
It makes me think of an architecture in Livecode using [[dispatch]] where a
stack is loaded that contains the needed code should the dispatch call not
be handled by the message hierarchy - by default this stack could be
deleted after it is called - so releasing it from memory. Commonly called
handlers could be loaded before hand by a different command and therfore
stay in memory.
On 7 April 2015 at 21:21, Andrew Kluthe <andrew at ctech.me> wrote:
> >>1. Livecode messaging is fully asynchronous. Not semi-async.
> Right, when I said semi-async I was referring to the single threadedness of
> livecode (which node shares) along with all the baked into livecode stuff
> that blocks up messages currently: accessing a large file on disk, posting
> some information to a web service with a large json payload being returned.
> It's async, with some pretty hard to work around exceptions (url library
> specifically has been the primary source of past frustration in this way).
> >>3. Livecode does not have closures = passing anonymous callbacks as
> params to functions so they can be executed later
> As for anonymous callbacks, I totally agree. Most early Node development
> had to overcome the callback hell that these patterns introduce. However,
> almost all of the nodejs projects and libraries I've worked with leveraged
> them heavily or exclusively. Promsies seem to have become the standard way
> of dealing with the callback hell that node was so famous for for a long
> time. Why does node use anonymous functions over the method you linked to
> in the article? Anonymous functions are marked for garbage collection
> immediately after being returned. All other functions at the global scope
> run the risk of needlessly using memory after they run. I've gotten into
> some hairy situations with memory management with these kinds of named
> callbacks (specifically for database access and return of lots of results
> when not scoped correctly).
> Passing a function (not just a name of a function to be used with a send or
> a dispatch later on) as a parameter even in your article still demonstrates
> something LC just can't do currently. In the article he's still using
> closures, it's just got a name instead of being anonymous. It's still a
> closure. LC has ways to accomplish similar things by passing names of
> functions and using dispatch, but I think it's not exactly the same.
> Closures are part of the reason node.js works the way it does and closures
> certainly possible to do async without them, but closures are what makes it
> easy and kind of a fundamental principle to working in node.js.
> >>4. But we can easily call / dispatch calls to functions by passing names
> around and we can limit scope by using private handlers or libraries.
> Sure, there is nothing STOPPING us from implementing named callbacks in the
> current fashion or passing the named callback references dynamically as you
> and I mentioned, but from experience trying it this way I feel like it
> makes maintaining large projects built this way a lot more difficult. To
> the point where I ended up completely redoing most of the livecode stuff
> I've written in this way early on because it was getting to be a nightmare
> to maintain a completely separate callback functions rather than the sort
> of nested structure you get in node with callbacks. It takes a lot of
> discipline in placement and grouping of the code that is related in this
> way to come back later and make sense of it. In summary: it can be done,
> but that doesn't mean that it SHOULD be done.
> Kind of a weird long post there. Sorry for the length and probable
> repetition of my points.
> Also, this was something really neat I've used recently to make node work
> in-process with some .NET applications we have. Something that does this
> with node and LC would indeed be the bees knees.
> Specifically the part about it allowing us to write node extensions in C#
> in addition to the standard C and C++ way of doing it. I'd love to be able
> to hook node into extensions written in livecode.
> On Tue, Apr 7, 2015 at 12:24 PM Richard Gaskin <ambassador at fourthworld.com
> > David Bovill wrote:
> > > OK. A few questions... I'll post them as assertions to aid clarity.
> > Personally I find it clearer to read questions as questions, but with
> > that explanation I can work with this:
> > > 1. Livecode messaging is fully asynchronous. Not semi-async.
> > What is "semi-asynchronous" in the context of LC?
> > There is a distinction between "asynchronous" and "non-blocking" that
> > I'm not entirely clear on, so I'll use "non-blocking" for now:
> > Socket I/O messaging can be non-blocking when the "with <message>"
> > option is used, e.g.:
> > accept connections on port 8888 with message "GotConnection"
> > But this is of limited value within a single LC instance, since doing
> > anything with that message is likely going to involve blocking code
> > (e.g., reading a file or accessing a database, doing something with that
> > data, and then returning it).
> > So messages will keep coming in, but they'll queue up. This may be fine
> > for light loads, but when expecting multiple simultaneous connections it
> > would be ideal to handle the tasks more independently.
> > Many programs do this with threading, but we don't have threading in LC.
> > Instead of multithreading we can use multiprocessing, having multiple
> > instances of LC apps each working on a separate task.
> > The challenge is that to hand off a socket request to a child process
> > entirely would require us to have some way of handing over the socket
> > connection itself. I believe fork allows this, but I know of no way to
> > launch new instances of an LC app in a way that will hand over the
> > socket connection to them.
> > In lieu of being able to fork, two options I know of are the ones I
> > noted earlier; others may be possible as well, but these seem common
> > enough to be reasonable starting points:
> > <http://lists.runrev.com/pipermail/use-livecode/2015-April/213208.html>
> > > 2. There are a bunch of functions that are currently synchronous in
> > > LiveCode that make it difficult to create asynchronous code - such as
> > > certain network call like POST.
> > Yes, as above.
> > > 3. Livecode does not have closures = passing anonymous callbacks as
> > > params to functions so they can be executed later
> > Not per se, but as you note:
> > > 4. But we can easily call / dispatch calls to functions by passing
> > > names around and we can limit scope by using private handlers or
> > > libraries.
> > >
> > > Here is an article about why you should not use anonymous callbacks
> > > that seems interesting in the context of readabiity and literate
> > > programming languages:
> > >
> > Good find. While most of that is very JS-specific, the
> > readability/complexity argument applies in LC well. As a general rule,
> > I feel that "do" is a last resort when all more direct means of
> > accomplishing something have been exhausted, and even "dispatch",
> > "send", and "value" can have similar impact in terms of
> > debugging/maintenance.
> > I almost never use "do" anywhere, and on servers I limit use of the
> > others for another reason not mentioned in the article, security: since
> > they execute arbitrary code by design, "do", "dispatch", "send" and
> > "value" can potentially be sources of injection when used on any part of
> > incoming data.
> > I use "dispatch" in one place in my server framework, but only after
> > checking an incoming command argument against a list of known one-word
> > commands; any request missing a command parameter, or having one not
> > found on that list, returns an "invalid command" error message.
> > --
> > Richard Gaskin
> > Fourth World Systems
> > Software Design and Development for the Desktop, Mobile, and the Web
> > ____________________________________________________________________
> > Ambassador at FourthWorld.com http://www.FourthWorld.com
> > _______________________________________________
> > use-livecode mailing list
> > use-livecode at lists.runrev.com
> > Please visit this url to subscribe, unsubscribe and manage your
> > subscription preferences:
> > http://lists.runrev.com/mailman/listinfo/use-livecode
> use-livecode mailing list
> use-livecode at lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your
> subscription preferences:
More information about the Use-livecode