Control? Object?
Mark Waddingham
mark at livecode.com
Mon Jun 20 05:28:53 EDT 2016
On 2016-06-19 09:19, Richmond wrote:
> I am currently teaching some children Livecode programming and ran
> into some difficulty
> on Friday when a child asked me why the menus were full of the word
> "Control"
> when I had been talking about "Objects".
>
> Well?
>
> How about changing every use of the word "Control" to "Object"?
Replying to the original post, as a lot was mentioned in this thread (it
tries to cover most of what came up in the thread, not just this
particular question).
An object (regardless of what language it is rendered in, or with
whatever specific kind of 'oop' methodology you care to subscribe to) is
simply some state (i.e. variables which are distinct for each instance
of the object) with an associated list of handlers/methods/functions
which act on that state. (Indeed, really I think one should require that
the state is entirely hidden and encapsulated within the object and not
visible from the outside world - although most OOP languages do this
very very poorly).
In LiveCode, this is perhaps slightly hidden behind the English-like
syntactic sugar. For example, one can imagine that:
get the fooBar of myObject
Is the same as (in a non English-like language):
it := myObject.GetFooBar()
Or something like:
copy myObject
Is the same as (again, in a non English-like language):
myObject.Copy()
Therefore, I have absolutely no hesitation in saying that LiveCode is
object-oriented (for some definition of object-oriented). Indeed, it
always has been - everyone who has ever programming in an xTalk had been
doing object-oriented programming since it started to become 'popular'
(HyperCard appeared in 1987, Cfront - the original C++ - appeared in
1985 - although the first 'object oriented' languages such as Simula
appeared perhaps a decade before).
The reason why I tend to hesitate saying LiveCode is object-oriented
explicitly (well, up until 8, at least) is that the kind of way you do
programming in LiveCode is perhaps not quite the same as what people
expect when they hear that 'a language is object oriented'. The LiveCode
model is essentially that of aggregation and adaptation, rather than
inheritance (people tend to be highly aware of the later, but not aware
of the former even though they will be implicitly doing it
day-in-day-out in any programming language they are a practitioner of).
In LiveCode, you build applications by using the building-blocks you
drag from the control palette to build more complicated things
(aggregation), and then you apply scripts to each object to change the
behavior of the building-blocks appropriate to your app (adaptation).
Now, inheritance is orthogonal to the idea of aggregation and adaptation
- and it should be noted that most 'traditional' OOP languages allow you
to do inheritance, but you have to build the framework to do aggregation
and adaptation yourself (hence why Java, Obj-C, C++ etc. all have a
large variety of 'frameworks' you can leverage to actually build apps -
if you tried to do so with the 'raw' language, you'll find yourself just
reinventing some sort of structure which is probably not too dissimilar
to LiveCode's).
When we added 'behaviors' you could argue that 'inheritance' did
actually start to creep in - behaviors allow you to factor out the code
which you use to adapt the building blocks (i.e. your scripts) into an
informal hierarchy. (Informal here refers to the fact you don't need to
make type definitions - which is entirely appropriate to LiveCode which
tends not to force that kind of thing on you anywhere - except in
Builder, and only then if you really want to).
With 8, however, you can start to see the 'class inheritance' ability
being added to LiveCode - that is what widgets are. i.e. You can write
your own building blocks (in LiveCode Builder). (For those of you who
have looked at Builder, then although it is not yet explicit - a module
is essentially a class - a widget is a module which can have multiple
instances and a library is a module which only ever has a single
instance).
So, right now in LiveCode, the objects you have to play with are stacks,
cards, audioclips, videoclips, fields, buttons, scrollbars, players,
images, buttons, groups, graphics and widgets. However, remember that
'widgets' are a completely extensible set of things, so this list is no
longer fixed as it was before.
To go back to the original point about controls vs objects then this is
actually very well defined (indeed, it is embodied in the source of the
engine - i.e. how LiveCode is actually implemented). A control is an
object which sits on a card or in a group.
Indeed, you have the following 'inheritance' hierarchy:
Object
Stack
Card
AudioClip
VideoClip
Control
Group
Field
Button
Scrollbar
Player
Image
Button
Graphic
Widget
<all widgets>
This means that a stack is an object, but not a control. A player is a
control, and therefore an object. AudioClips and VideoClips aren't
really 'controls' in this sense because they sit on a stack , and not a
card (although the Import Menu does call them so - which is perhaps the
reason for the slight amount of confusion).
At runtime, objects in LiveCode form themselves into a tree (note this
tree is about *ownership* of instances of objects, not inheritance):
Stack
Substack
<same as stack>
AudioClips
Videoclips
Cards
Controls
Groups
Controls
You use LiveCode Script to attach 'adaptations' to your objects, and the
message path allows a simple way for these adaptations to communicate.
As LiveCode Script does not have 'strong references to objects' (and
cannot have them unless we want to lose stringyness entirely - which is
actually one of the main differences between Script and Builder) you
create named objects in this hierarchy and then manipulate them using
chunk expressions - i.e. references are strings describing a path in the
object tree such as 'button "Foo" of card "Bar" of stack "Baz".
Another way to think about this is that, in LiveCode Script, every
object must have an explicit name. You use chunk expressions to select
an object based on various criteria (type, owner). Once created, objects
exist in the tree until they are explicitly deleted.
Indeed, one of the reasons 'OOP as you see it in other languages' is
very unlikely to appear in LiveCode Script is because there is no way to
represent a reference to a temporary object which disappears when there
are no references to it. As all references must be strings, and strings
can sit in arbitrary other strings, there is no way for the engine to
ever know when you don't need an object anymore - you have to tell it. I
don't really see this as a limitation, however, because that is the
object model of LiveCode Script - you adapt named instances of building
blocks with your scripts!
Of course, it would be nice if you could write widgets in 'LiveCode
Script' - however, I'm not sure it is entirely appropriate. The stringy
type system which Script has compared to Builder means that some things
you really need to be able to do to write widgets in the way Builder
does become quite tortuous. That being said, there is room for 'Builder'
to come closer to 'Script' in terms of its strictness - at least as an
option - i.e. Script without the 'everything is a string' concept.
Perhaps the thing which is much more important at the Script level is
the ability to take a collection of LiveCode objects and scripts etc.
and wrap them up with an 'inner script' which presents them as a single
black-box control - just like a widget. This is the idea of 'template
objects', or custom controls 'done properly' (for some definition of
properly, of course). This is a recursive application of the ideas which
you are already familiar with when you build your apps and has a very
nice 'self-similarity' and symmetry ("It's turtles all the way down").
So, anyway, to sum up:
1) Objects and Controls are very well defined concepts in LiveCode
and always have been. There might be some places in the docs and IDE,
however, where it uses the wrong term and I that should be corrected
(i.e. if you notice an instance of this file a report, and we'll look
into correcting it).
2) LiveCode is definitely object-oriented:
i) You build black-box objects in LiveCode Builder (which is,
although not explicitly yet exposed, class-based).
ii) You aggregate black-box objects together then adapt and glue
them together using LiveCode Script.
3) LiveCode Script is designed to allow this rapid gluing and
adaptation, and as such has a loose stringy type-system and dynamic
message path to aid this rapidity.
4) LiveCode Builder could become less strict in the future as an
option, to make it easier for people who are familiar with Script to
write Builder to build widgets.
5) LiveCode Script is probably not the thing to use to write widgets,
but the ability to be able to package up a group of controls as a
black-box just like a widget would be entirely consistent and
self-similar with the existing environment.
The final thing which was touched on in this thread (and indeed was the
point of it originally) was about how to teach LiveCode to kids - and I
have to say that I'm not sure I'm qualified to actually help there! All
I will say is that surely kids at the level you are talking about are
able to reason about facts like:
i) A Car is Vehicle; a Lorry is a Vehicle; a Car is not a Lorry so
not all Vehicles are Cars
ii) A Potato is a Vegetable; an Onion is a Vegetable; a Potato is not
an Onion so not all Vegetables are Potatoes
Which has the direct analog with (something similar to):
A Control is an Object; a Card is an Object; a Card is not a Control
so not all Objects are Controls
Of course, having just written that, I do remember a number of computer
science textbooks I have read (which are aimed at undergraduates)
belabouring such points as these (almost in this direct fashion) - which
suggests that it isn't a very easy concept to get across even to those
who are 18+. i.e. I suspect it is more difficult to teach than I perhaps
imagine!
Warmest Regards,
Mark.
--
Mark Waddingham ~ mark at livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps
More information about the use-livecode
mailing list