Ideas about non-OO ways to implement and/or manage GUI's. No implementations given so far. Bulk of off page topic material moved to GuiConfiguration and DeclarativeGuiFrameworks. ---- '''Pure Functional GUIs''' (primarily ML-family language) An older but still very interesting research project on "Fudgets": pure functional composition of GUI widgets: http://www.cs.chalmers.se/ComputingScience/Research/Functional/Fudgets/ ---- Constraint-based language GUIs? Constraints are '''part''' of many GUIs... Logic language (Prolog) GUIs? Scripting language GUIs (e.g. PerlGuis) are of interest, but I don't think they constitute a different paradigm, so this page may not be quite right for those. Declarative languages usually seem to be either logic based or concern only configuration (e.g. XDefaults), but if any involve a different paradigm, they might be of interest here. Are any of the XML-based GUI languages new paradigms?? ---- ** This section raised some things (LispMachine, Gnome) that turn out to be inappropriate to even be on this page in the first place. We tolerate them here at what used to be the bottom of the page, but putting off-topic material as the first thing on a page makes no sense whatsoever. ''So far, most of the discussion has focused on (seemingly speculative) table-oriented methodologies, but I don't see why functional and procedural shouldn't be included.'' * Pure functional, yes, but not procedural. I take the point of this page (other than being a mouthpiece for Top) to be roughly "What about all of the non-typical GUI approaches?". GUIs have always been done procedurally, OO, or mixed procedural/OO, so if we included those traditional ways, we'd have to list every GUI every invented on this page. LispMachine''''''s had some of the first guis. Did they use CLOS to implement it? Also, the GnomeDesktopEnvironment is written in straight CeeLanguage. [[Object oriented code can be written in any language, missing features can be faked, but OO isn't a language thing, it's a way of thinking. Some languages support that thought process better than others, but that won't prevent an OO programmer from writing OO code, as Jonathan says, Gnome is OO. CLOS is awesomely OO.]] * That's all true, and involves interesting subjects; it's just that none of that means that e.g. Gnome should be discussed on '''this''' page, right? We can continue such discussion on an OopGuiMethodology page if desired. ''They had GUIs before GUIs were universal, but I don't think it's quite accurate to say "some of the first guis", which were around on minicomputers, mainframes, and special purpose systems for decades before they became universal.'' [LispMachine''''''s used Flavors for the GUI. That's the precursor to CLOS, and is, by Lisp standards, ObjectOriented (I'd also argue that it's significantly more powerful than conventional OOP, but that's just MHO). Gnome is object-oriented, despite being written in C. They make this very clear in the docs, and implemented their own object system (GObject) to use. -- JonathanTang] I.e. LispMachine was OO, and Gnome is procedural + OO. ---- I still haven't seen anything I'd consider non-object oriented GUI programming. Perhaps my understanding of objects is broken. I consider an object to be a construct that combines data (state) with associated behavior. I don't see how you can usefully define a GUI widget in any way that it is not also an object. Thus, whatever method you use to define and/or implement your GUI (most of the declarative approaches to GUI design are just layout generators, actual behavior is in some other sort of code). The terminology varies, and you often lack most of the explicit object support of an OO language, but you're still dealing with entities that maintain their own state and have their own sets of behavior. I consider this an object. ''There is too much anthropomorphizing, such as "maintain their own state", in that statement to really compare it with the various OOP definitions (NobodyAgreesOnWhatOoIs). I also perhaps see a case of OoConflictsWithCollectionOrientation. For example, what if I want to list the values of every widget (that has values).'' Maybe I'm just confused. I don't spend a lot of time researching object oriented programming or the subtle intricacies of set theory and how it applies to computer science. I consider objects to be a conceptual mechanism that you use to associate data and behavior and OOP to be programming techniques that take advantage of that conceptual distinction. I work with GUIs all day (and night, sometimes...), and maybe I'm just too entrenched. I don't have any problems with enumerating every widget and trying to get its value. In fact, I just finished doing exactly that as part of a framework for JavaScript/HTML form validation. How does that conflict with OO? I still treat each widget as an "object" that is an entity with unique state and behavior. I didn't do it using relational methods, of course, I did it using iteration over the DOM. In more traditional GUI toolkits, I'd iterate through parent/child relationships. I guess if you really, really liked relational systems you could treat your widgets as records use queries to get & set data, but you still need to have behavior tied in somehow and once you start sticking event handlers into fields in your record you're doing OO - you're associating behavior with a discrete chunk of data (your record). -- ChrisMellon (I wrote the above as well, and forgot to sign it.) ''Languages have been mixing data and behavior long before OO was "invented". Besides, DataAndCodeAreTheSameThing, and in theory relational allows one to see any viewpoint/grouping that they damned please. How stuff is grouped is merely a temporary viewpoint on stuff. You want X grouped with Y, you can. You want A grouped with Z? You can. You gotta learn to cast aside of the realm of Cartesian coordinates and think multi-dimensionally and virtual. See SeparationAndGroupingAreArchaicConcepts. Being rooted in physical simulation, I think OOP is limiting people's thinking to the physical 3D world where things are either with an "object" or not with it. We don't have to be bound by such a restriction. With-ness can be relative.'' I know languages have been doing this. People doing it and seeing the benefits are what prompted the development (or formalization, if you will) of OOP. I'm willing to accept that there are benefits from other viewpoints (although I've been thinking in objects for a long time and I see them everywhere, so I may have a hard time grasping other viewpoints rather than interpreting them in terms of what I know. I suspect some of the relational advocates I've seen on the wiki may have the same problem). I don't see how arbitrary remapping is useful in the context of a GUI, though. To be frank, I'm not even sure what you mean by it. You call something a button and you give it a specific set of behaviors, and data to store that behavior. The conceptual metaphor gets a lot firmer because people actually interact with it as if it were a discrete entity - I think this sort of interaction makes the case for OO in GUIs much stronger than it is for arbitrary business objects, which may or may not actually correspond to real-world entities. ''Here is an example advantage of a "loose" association. Suppose you created an event code snippet X that is triggered when the button is clicked (a typical "on-click" event). It turns out later that there are multiple ways to trigger it, not just the button. Or perhaps we want it triggered when somebody clicks on an image instead of a button. If we view the association between X and the button as fluid or loose, then we simply change or add references. We don't have to "move" code. This goes against the philosophy of OO encapsulation and ResponsibilityDrivenDesign. Changing references instead of moving is one approach to making software change-friendly. And if you want to know what references what, you just query. -- top'' [I believe this to be a misrepresentation of OO thinking. It certainly is not how I write OO code, nor does it match the reality of (good) real-world GUI code. The "behavior" associated with the button is not necessarily, say, "Insert data into this field". This is actually a violation of ResponsibilityDrivenDesign. MVC is one of the oldest GUI techniques, heavily used in OO GUI code (see SmallTalk), and it addresses this exact issue. OO ties well to GUI programming because a button on the screen (a "thing", and treated as such by the user) is a "Button" in the code. SeparationOfConcerns is handled by the event-based portion of it, which is modelled by MVC. One of the flaws of "form designer" based tools like VB and Delphi is that they make writing code like you describe. See Apples XCode (especially in Tiger, Core Data yum!) for one that gets it right. -- ChrisMellon] ''MVC is messy in my opinion. If you have a specific flaw scenario of "form designer" tools outside of the resize issue, I'd like to see it. (However, I think there's existing topics that cover such a HolyWar.) --top'' Separation of concerns is sometimes taken too far and can get fuzzy because in real life the boundaries are fuzzy. If only one widget triggers a given action, then the indirection/interface required to separate it can be code bloat. I suggest waiting until multiple things reference a given action to move/relink it to a shared spot (YagNi). ------- '''Links to Table-Oriented GUI Suggestions''' http://www.geocities.com/tablizer/guitable.htm http://www.geocities.com/tablizer/prpats.htm#guievents Related diagram: http://www.geocities.com/tablizer/gui2.gif Note that I feel that DynamicRelational is better suited to GUI's than the current static RDBMS's. In general, here is how this table-oriented GUI system would handle a button being pressed. When the button is pressed, the GUI engine first "sifts" through the "event-dispatch table". The result may be one or more matches, ordered by both default and explicit (if used) priority numbers. Each event in the result list is then "executed" in order. The name of the subroutine(s) is part of the event table. These routines are executed in the given order and the "view table" is potentially updated if there are screen changes. After all the events are executed, the client is then refreshed based on the changed to the view table. (A flag may keep track of what was added or changed.) Note that one does not necessarily have to design an (original) screen by entering data into a table, for a GUI designer may be used instead. --top ''Where and how are typical Button1 and Button2's captions stored? As a text field in the column of a table? Where and how is a button's glyph image stored? Relationally?'' In a table(s), of course. It would in some ways resemble a DataDictionary. There's a contentious discussion somewhere around this wiki on how "custom" attributes should stored. I'll try to re-find it. My favored approach is DynamicRelational so that a distinction does not have to be made; but barring that, I'd go with a "standard" widget table for the common attributes and some kind of AttributeTable for the uncommon or custom ones. As far as where images are stored, they could be stored in some brands of RDBMS, but I'd personally prefer a URL link to an image file, like HTML does. By the way, the distinction between "button" and "clickable thing" (such as an image) is fuzzy enough that perhaps they should not be considered different things. A button is sub-set or extension of clickable thing. Thus, using HAS-A thinking may be more flexible than IS-A thinking. (And, large-scale HAS-A is messy in OO in my opinion.) ------ This is a rough-draft of a relational GUI schema. table: widgets -------- widgetID // internal-generated widgetName // reference name (possible alternative to auto-ID) widgetType // button, form, textbox, etc. Foreign key to // ... WidgetTypes table widgetTitle containerRef // foreign key to container widget ID orderSequence // sequence if in flow-based layout (double) X Y Z // depth, such as overlap resolution contents // Actual field contents or default value overFlowRef // Reference record if value oversize for non-dynamic DB's wgtTypeRef // type name (see types table) maxLength dataTypeRef isReadOnly isHidden isRequired alignment // Percentage: 0.0=left, 0.5=center, 1.0=right columnRef // DB column reference for "bound" widgets tableRef // DB table/view reference for "bound" widgets styleRef // style ID fontModif // -1 for smaller, 0=default (per style), 1=large, etc. table: events --------- eventID eventType // click, change, focus, close, etc. ("on_" prefix implied) priorityOverride // custom priority if not using default. Range: 1-to-100 widgetRef action // code snippet or function name to execute table: constants ---------- constantID constGroup constValue constDescript constDisplayOrder // (DOUBLE) table: customAttributes ---------- widgetRef attrib attribTypeRef ca_value table: styles --------- styleID backColor foreColor borderColor fontCateg // general font category such as san-serrif fontName fontSize fontUnit baseFontRef // optional reference to a base font if some elements not defined imageMap // (file location) background image imageSpread // "proportion", "stretch" (to fit), "tile" frameImageMap // Image used for shading frames (center out method) table: dataTypes ------------ typeName // primary key typeDescript baseType // CHAR=character/text, NUM=number, INT=integer, DT=date/time, CUST=custom formatTemplate // reg-ex-like format template validationRoutine // reference name or code snippet to validate value formatRoutine // routine to format value for display isQuoted // if quoted for SQL usage. Notes: * Forms and containers are also "widgets". * Tabbed panels can use the Constants table to give names to the various panes and reference the various forms. A custom attribute is then used to specify the "constant group". * It's assumed that the schema is not easy to change. If DynamicRelational existed, other options could be considered. Related: GodGuiWidget. --top ---- I'd argue that any GUI ends up reinventing OOP in some way or another. Take a button for example. In any non trivial GUI, eventually you are going to have to reuse the button (or panel, checkbox) and inherit from it. If you want a special button you are going to have to '''derive''' from your original button. '''Deriving''' is the whole point of OOP. So whether you store the buttons data in a STRUCT, or CLASS, or TABLE, you are going to end up using OOP techniques to '''derive'''. The Windows API is considered procedural - but it also has an OOP smell to it. A table oriented GUI would still end up using OOP techniques in the end if you wanted to reuse the widgets and inherit from them. I'd argue that there may be no such thing as Non OOP GUI methodologies - the title is a paradox or contradiction. A widget, is an object. Gui's have widgets. Therefore GUI's are by nature, object oriented. If you don't like the term "object oriented", consider "structure oriented". Widgets are structures. All Gui's have widgets. All gui's have structure. You can't get around this. Objects are just structs with bonuses. Some gui's are more object oriented than others - some GUI's utilize inheritance more than other GUI's. But since widgets are objects (widgets are things, widgets are structures) they are all basically object oriented - no matter what you use - functional, procedural, classes, tables. If it isn't structure oriented or object oriented, your GUI is going to be widget oriented, since it has widgets - so it boils down to a semantic war. I LaughOutLoud when I see things like "pure functional gui". I'd like to see a GUI without side effects. The GUI would essentially be useless. GUI's are side effects galore. So if pure functional has side effects, then I demand a definition of what functional programming actually is, because it certainly is not clear, and languages like Lisp haven't helped add clarity to what functional programming is. ---- See also: RemoteGuiProtocols, TooMuchGuiCode, GuiConfiguration, LanguageNeutralServices, JavaEventHandling, ProgrammingLanguageNeutralGui, GuiMachineLanguage, TableOrientedGuiDiscussion ---- CategoryGui, CategoryPerpetualArgument