Equivalent of classes in LiveCode

LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

bogs
Posts: 5480
Joined: Sat Feb 25, 2017 10:45 pm

Re: Equivalent of classes in LiveCode

Post by bogs » Fri Jul 17, 2020 1:54 pm

@Brian -
Thanks for that man, I had lost track of those two articles, was a nice re-read!

@Andrew - I'd pretty much have to concur with everyone else, in that if you are looking to use Lc like you would use C/C++ outside of generic rules of programming, you are very likely to have a very frustrating and often times ugly trip. You've been around long enough to remember, I'm sure, how programs were written in a pre-gui environment where your program worked at the CLI. There was no OOP then in the strictest sense of the word, and there is none (again, in the strictest sense of the word) in Lc outside the objects you see in the IDE as was mentioned earlier.

If you try to approach programming in Lc like you listed for C/C++, your also going to be severely frustrated in most cases (not all, since for many of my own projects I tend to code to solve the problems first, then add the gui after), however the cases where I do that now are far more rare than when I started with Lc.

Some of the things you wrote that jump out at me -
My normal mode of development is build the data handlers and functionality, as divorced from the environment as possible, both operating system and UI, and then add in the dependencies of the operating system vendors and UI around the core functionality.
You can certainly take this approach in Lc or any RAD language, but you are almost always going to do it the reverse way to this when developing in a RAD environment, i.e. you are going to need to visualize what your program should look like in it's sparse state, what controls you are going to want your end user to have, and then lay out the program visually.

For one thing, unlike C/C++, you are not trying to tie your program to some framework outside of the language, in almost ALL RAD languages, the buttons, fields, and other gui elements are already there.
So I have a library of C++ classes that handle a lot of that core functionality. Now the trick is to layer a UI on top, as well as data collection that delivers data down to the core C++.

What it sounds like is, you don't want to have to re-write functionality you've already written in Cpp, you just want a frame work that you can tie it to so it will be x-platform. I really don't think this is going to work out for you if that is the goal you have in mind.
My application is based around a database. I have a number of similar tables that have common fields, with common functionality. So I have base classes that implement core Sqlite access functionality, subclasses that drive sets of more subclasses for tables with similar structures and so on.
The part in bold is all that I saw that was important to a discussion on Lc in particular. Lc can do databases, and certainly can do sqlite dbs. If you have a db already existing, you can build a program around it quite easily in Lc, and you can replicate your "best not messed around with" stuff as it applies to db's, without re-using Cpp. Lc has a lot of functionality built into it specifically for dbs, but, you can also use the db's native calls couched in Lc statements.
There is lots down there that the user really wants to avoid seeing or even knowing it exists. But for those parts of the records in particular tables that they do need to see and interact with, that is where I would need to map certain fields of those database tables to be displayed in tables for the user to interact with.
I don't see the problem here, either. If you don't want them to see it, don't show it, the parts you want shown, design the layout you want shown, and show it.
In some cases a record that is displayed to the user has fields from multiple database tables that are related. I do have a mechanism for describing these meta-tables so that data can be delivered to the UI and collected from the UI.
All of this is already built into Lc, joins from dbs are already built into db languages.
My core C++ database Class library is probably best not fooled with,
At that point, I don't see how you are going to interface your db classes with Lc. I sure wouldn't suggest trying to use them with Lc, although Mark may know better as he pointed out some options I wouldn't even try (or need).

IF you are seriously contemplating switching this type of project *to* Lc, I would suggest taking a look at the functionality those core classes you absolutely don't want to touch provide, and see how to get that functionality out of what Lc can provide. I'd find it very hard to believe the functionality isn't reproducible, but that is up to the one trying to do the work to determine or ask about.
Image

aetaylorBUSBnWt
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 118
Joined: Thu Sep 20, 2012 5:11 pm

Re: Equivalent of classes in LiveCode

Post by aetaylorBUSBnWt » Fri Jul 17, 2020 2:36 pm

Hi,

I can accept that I will be changing how I go about programming, especially the UI, but throwing away lots of core code that works is also a nonstarter. One of the things that I have told people is that programming is nothing more than embracing a lifetime of accelerated learning.

I was just trying to acquaint you with what I had, where I was coming from and what I was facing and looking for suggestions.

Part of my motivation came from the initial posts where I saw misunderstandings of terms, but not enough useful information to move forward.

Hopefully this conversation will continue to expand how to switch to non-OOP, but also how to utilize existing libraries and the net result of this conversation will leave a record and a direction for others (and me of course).

I have been copying down the links and bits of advice that come about. They all should help as I go through the tutorials and learning process and implementing my project. Thanks!

By the way, I was one of the contributors to the KickStarter campaign back in 2013 to take LiveCode open source. I contributed enough to get myself a lifetime commercial license. Unfortunately life took a turn and it took me until now to get back to the project I am working on now.

The good news is that you guys have since pushed/helped RunRev develop and expand LiveCode quite a distance since then.

Any others care to share what they needed to do to convert from a C/C++ or other world to LiveCode?

Andrew

bogs
Posts: 5480
Joined: Sat Feb 25, 2017 10:45 pm

Re: Equivalent of classes in LiveCode

Post by bogs » Fri Jul 17, 2020 3:01 pm

Heya again, Andrew :)
aetaylorBUSBnWt wrote:
Fri Jul 17, 2020 2:36 pm
I can accept that I will be changing how I go about programming, especially the UI, but throwing away lots of core code that works is also a nonstarter.
Hopefully to be clearer than my above post was, I'll start out by saying I was not suggesting you throw away the core code, my suggestion was meant to say that you look at it and re-apply it in Lc or sqlite terms and language. This will almost always give you the cleanest result.

The concepts will almost certainly translate, you don't have to rethink the entire problem and then re-code it. I think you will most likely find this part to be almost trivial. However, as I also said, perhaps others who have already done parts of this in the current IDE will have a way for you to keep it and combine it intact.

I am not the best source in this regards, I use an antiquated pre-version of the IDE and language, and there have been changes made I have little to no understanding of, or use for, such as FFI. What I *think* I understand about it is that you are supposed to be better able to drop into other languages when using it, but again I don't have the knowledge myself to explain it.

Good luck in your quest, I'll leave the rest of the thread for your goal to move forward in.
Image

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10045
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Equivalent of classes in LiveCode

Post by FourthWorld » Fri Jul 17, 2020 5:32 pm

aetaylorBUSBnWt wrote:
Fri Jul 17, 2020 2:36 pm
I can accept that I will be changing how I go about programming, especially the UI, but throwing away lots of core code that works is also a nonstarter.
Wouldn't writing new code be an inherent part of using a new language?

How much Pascal can one copy-and-paste into a C++ compiler and expect to run?

I think I'm missing something on that part.
One of the things that I have told people is that programming is nothing more than embracing a lifetime of accelerated learning.
Amen to that, brother.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Equivalent of classes in LiveCode

Post by mwieder » Fri Jul 17, 2020 9:11 pm

Andrew-

if your intention here is to take an existing OSX app and make it cross-platform, I think you're likely to get discouraged along the way. If you're willing to discard some of the core code (*not* the core logic) and rethink it from a different perspective then I think you'll be pleasantly surprised. But I don't want to set up false hopes here... if you need to keep your database objects intact in Xcode and link to them you may be getting into more work here than is reasonable.

aetaylorBUSBnWt
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 118
Joined: Thu Sep 20, 2012 5:11 pm

Re: Equivalent of classes in LiveCode

Post by aetaylorBUSBnWt » Tue Aug 04, 2020 1:14 am

bwmilby wrote:
Fri Jul 17, 2020 5:15 am
I ran into these two articles a while back that may be interesting to you:

http://newsletters.livecode.com/novembe ... etter2.php
http://newsletters.livecode.com/novembe ... etter2.php

It is about using groups to implement classes and inheritance.
So for anybody following this and future readers, the answer to the question of this thread is YES!

I have finally learned just enough to understand what the above two articles were saying.
Yes it is a little verbose, but this method of using Buttons as CLASS definitions and then GROUPS as the instantiated object does indeed provide a very close approximation of a C++ class and object structure with inheritance and overrides methods in higher level class methods in the class hierarchy.

I don't believe that multi-inheritance is possible with this mechanism, but that is something that I rarely used anyway.

One part of the articles that was not at all clear, I eventually found in the LiveCode User Guide:

"If multiple objects share the same behavior, each will have its own set of script local variables. Any
references to me, the owner of me, etc will resolve to the child object currently executing." (page 133)

The above is part of the paragraph on "Writing reusable code using behaviors".

While this may be obvious, I am going to spell it out. The key issues here are that there is one set of methods, overridden as desired AND each instantiated object has its own copy of the fields. This is what happens with C++ Classes and Objects. The mechanism is that through a combination of linking of a Group object to a Button Object, the code (Scripts) can be inherited and overridden as desired. So the code functions the same way C++ methods are inherited and overridden. You do need to provide the Class parent link explicitly in each subClass via a "getProp parent" function where the code returns the name of the Button object that acts as the superclass.
getProp parent
return "Particle" //this is the name of the super class (a Button)
end parent

While the above web articles talk about assigning the behavior of a Button to a Group to connect the Button's Scripts to the Group, it does not say that LiveCode, as part of that functionality, makes a separate and distinct copy of the Script's "Script level variables" (which we can call fields) that is then assigned to the new Group object. If you already know LiveCode this is obvious, but to programmers coming into LiveCode this is not clear at all until you get through 133 pages of documentation and recently read those Web articles.

The hierarchy of code is achieved by encapsulating each instantiated object (a Group object) INSIDE of its superclass object(also a Group object). This way the LiveCode messaging passing protocol automatically calls the "superclass object" if a given level in the hierarchy does not implement that "method". Each method implementation can also "pass" the message up the hierarchy as desired. This encapsulation process is implemented in the "newObject" function of the OOPEngine library.

The OOPEngine does not implement the equivalent of Constructor/Destructor methods found in C++, but they could be added to the newObject/deleteObject functions in the OOPEngine.

Read the above articles, yes 8 (EIGHT) years old but very relevant, download the Particles.livecode stack file, play with it to see more of the calling/coding conventions, pull out the OOPEngine stack and you are good to go with an equivalent of C++ or Objective C or any other kind hierarchical class programming language.

Hey RunRev People! (and anybody who has a connection to them) - please get the referenced articles into your formal documentation and point to it for "Programmers coming from other Languages". (and maybe make it part of your library base as well!)

Thanks,
Andrew

aetaylorBUSBnWt
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 118
Joined: Thu Sep 20, 2012 5:11 pm

Re: Equivalent of classes in LiveCode

Post by aetaylorBUSBnWt » Tue Aug 04, 2020 1:26 am

bwmilby wrote:
Fri Jul 17, 2020 5:15 am
I ran into these two articles a while back that may be interesting to you:

http://newsletters.livecode.com/novembe ... etter2.php
http://newsletters.livecode.com/novembe ... etter2.php

It is about using groups to implement classes and inheritance.
Oh and THANK YOU Brian for remembering and finding these articles!

Andrew

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7391
Joined: Sat Apr 08, 2006 8:31 pm
Contact:

Re: Equivalent of classes in LiveCode

Post by jacque » Tue Aug 04, 2020 4:45 am

I don't come from another language and what you said made only the vaguest sense to me, but I can clearly see how the light dawned and it made me smile. Welcome to the club, I think you are going to love LC. :)
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Equivalent of classes in LiveCode

Post by mwieder » Tue Aug 04, 2020 4:33 pm

Thanks to Brian for uncovering those articles - I had either missed them or forgotten them.

Andrew- wow - you've ingested a lot of LiveCode in a short time. A few comments here:

First of all, those articles were written quite a while ago, before the Big Change. The content is perfectly valid, but...

Behaviors are no longer limited to buttons. Yes, buttons can be a very convenient place to organize class information, but you can also use other objects, and script-only stacks provide a way to use text files to store the information. And you can convert them to substacks when you create standalone applications. But see below re: groups.

Also, behaviors can now be chained, so the "parent" property described in the articles is no longer strictly necessary. By setting behaviors you can subclass a subclass.

I do have one problem with the approach laid out in the articles, and that's with inheritance by nesting groups. In doing so you're inheriting from an instantiated object rather than from the class, and I think it makes more sense from an architectural point of view to set the properties in the class object, either with getProp/setProp handlers or by inheriting properties on a call to newObject.

Constructors and destructors are gonna take a little more thought. Constructors especially.

aetaylorBUSBnWt
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 118
Joined: Thu Sep 20, 2012 5:11 pm

Re: Equivalent of classes in LiveCode

Post by aetaylorBUSBnWt » Sat Aug 08, 2020 12:24 am

mwieder wrote:
Tue Aug 04, 2020 4:33 pm
Thanks to Brian for uncovering those articles - I had either missed them or forgotten them.

Andrew- wow - you've ingested a lot of LiveCode in a short time. A few comments here:

First of all, those articles were written quite a while ago, before the Big Change. The content is perfectly valid, but...

Behaviors are no longer limited to buttons. Yes, buttons can be a very convenient place to organize class information, but you can also use other objects, and script-only stacks provide a way to use text files to store the information. And you can convert them to substacks when you create standalone applications. But see below re: groups.

Also, behaviors can now be chained, so the "parent" property described in the articles is no longer strictly necessary. By setting behaviors you can subclass a subclass.

I do have one problem with the approach laid out in the articles, and that's with inheritance by nesting groups. In doing so you're inheriting from an instantiated object rather than from the class, and I think it makes more sense from an architectural point of view to set the properties in the class object, either with getProp/setProp handlers or by inheriting properties on a call to newObject.

Constructors and destructors are gonna take a little more thought. Constructors especially.
Hi,

Well, yes I have attempted to learn a lot, not sure it is sticking yet.

What was the "Big Change" - while I got involved early on, I have been away from LiveCode for years.

One of the things that intrigued me about those articles was the simplicity involved in setting up the Script variables and the way that they are inherited. Before I read those articles I had started down the path of using Properties.
Basically, unless they have a lot of functionality that I am missing, setting up Properties is a pain. It takes a lot of time to do all that clicking and typing to get them into a single object. Then they are "special" instead of the general availability provided by a Script variable.
Or is there a way I can skip all that GUI clicking nuisance and set up the properties in the "Button"/"Group" Scripts?

Nice to know I can set up behaviors in other objects. So does that mean that instead of needing both a button (the class) and a Group to instantiate it into, one could just use Groups?

As far as text files to store information and then setting up subStacks, it is not clear to me how that gives me a class hierarchy and inheritable variables. If I have a subStack, I would have a set of variables local to that Stack and its Scripts - so giving me a single instance of that functionality. What am I missing?

"Chained Behaviors" - how does this work? (just found the LiveCode lessons on behaviors, so I might find the answer there).

Please expand upon how to inherit properties via the call to newObject?

Thanks,
Andrew

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10045
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Equivalent of classes in LiveCode

Post by FourthWorld » Sat Aug 08, 2020 12:30 am

When you use Behaviors, every object subscribed to a behavior has its own set of instance variables as it uses the Behavior script.

Simpler than using added GUI objects (unless of course those are things your user needs), and even simpler than properties in some respects.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Equivalent of classes in LiveCode

Post by mwieder » Sat Aug 08, 2020 12:41 am

When you use Behaviors, every object subscribed to a behavior has its own set of instance variables as it uses the Behavior script.
Ah, yes and no.
In playing with this over the last couple of days, I'm finding that instance variables in chained behaviors don't work properly, i.e,

object1 -> behavior1 -> behavior2

if behavior1 has

Code: Select all

local mBehavior1Variable
and behavior2 has

Code: Select all

local mBehavior2Variable
then object1 has access to mBehavior1Variable but mBehavior2Variable will be empty.
Even using getProp and setProp handlers in behavior2 doesn't help.
I'm finding this distressing and I'm hoping someone can prove me wrong about this.

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Equivalent of classes in LiveCode

Post by mwieder » Sat Aug 08, 2020 12:45 am

What was the "Big Change" - while I got involved early on, I have been away from LiveCode for years.
Andrew- sorry to be opaque about that. I was referring to when we went Open Source and thus uncovered some of the internal mysteries. And there have been significant upgrades on many fronts over the last seven years.

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10045
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Equivalent of classes in LiveCode

Post by FourthWorld » Sat Aug 08, 2020 2:37 am

Interesting design challenge, Mark. The rule as I stated it seems consistent, in that behavior1 well have access to behavior2, just as object1 has access to behavior1.

How might we declare that vars in a nested behavior break this rule and be available to something other than its immediate subscriber?

How do OOPs handle this? Do they treat a behavior1 class as though it doesn't exist, and everything up the chain is effectively flattened for the bottommost object using any of them!
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

bwmilby
Posts: 462
Joined: Wed Jun 07, 2017 5:37 am
Contact:

Re: Equivalent of classes in LiveCode

Post by bwmilby » Sat Aug 08, 2020 3:06 am

Can we see code examples? Here is something that I threw together to test:
https://github.com/bwmilby/lc-misc/tree ... BehVarTest

Here is a couple of snips of the code (more in the actual stack):

Object1 button code:

Code: Select all

on mouseDown pButtonNumber
   put "=====" & lf before field "results"
   put "mouseDown:" && the abbrev name of me & lf before field "results"
   setBehavior1Var the short name of me
   setBehavior2Var the short id of me   
end mouseDown
Behavior1 button code:

Code: Select all

on mouseUp pMouseButton
   put "=====" & lf before field "results"
   put "sBehavior2Var is" && getBehavior2Var() & lf before field "results"
   put "sBehavior1Var is" && sBehavior1Var & lf before field "results"
   put "this me:" && the abbrev name of this me & lf before field "results"
   put "mouseUp:" && the abbrev name of me & lf before field "results"
end mouseUp
Behavior2 button code:

Code: Select all

function getBehavior2Var
   return sBehavior2Var
end getBehavior2Var
So the variables are maintained, but you will need to use functions/handlers to get/set variables in the parent script(s).

Post Reply