Code Conventions
Wins
- Create working code more quickly.
- Create maintainable code more naturally.
- Onboard new developers and other team members faster.
- Support creation of smarter development tools.
- Help support to be more focused and effective.
Contents
Concepts
Cookbook
Files
Names
Coding
Simplifying
Code
Concepts
Convention over configuration. It's what set Rails apart and made it successful.
Platforms with strong conventions are often referred to as "opinionated".
We prefer to think in terms of "organizing".
A good framework helps organize your code and organized code is code that is easier to understand and maintain over time.
Large applications and long-lived applications will, in the absence of strong organizing principles, become difficult to maintain over time. Good conventions provide a set of organizing principles, helping you build maintainable code naturally.
TIBET's conventions center around a few key principles:
- Separate library and application concerns. TIBET treats library code and
application code separately including rooting them on
TP
vs.APP
and loading them in separate phases. - Names matter. If two things are the same they should have the same name. If they're similar they should have similar names. If they're different they should have different names. Nothing is more confusing than poor or inconsistent names.
- Patterns matter. Names should follow predictable patterns so programmers and tools have a good chance of guessing and/or generating them. When you can guess what something will be named the result is a library you think of as "intuitive".
- Late bind all the things. Alan Kay, who coined the term Object-Oriented, said it consisted of three things: messaging, encapsulation, and "extreme late binding of all things". TIBET is heavily biased toward dynamic lookup patterns which help support API level "late binding".
- Metadata -> Metaprogramming. Lastly, TIBET focuses heavily on capturing metadata for use in reflection, method dispatch, and tooling. Many of TIBET's conventions and/or APIs are a direct result of a desire to capture or leverage metadata.

In support of these principles TIBET uses a number of conventions and coding standards that are specifically designed to speed development, enhance maintainability, and improve tooling.
You should be familiar with TIBET's coding standards as outlined in these documents:
You should follow JavaScript: The TIBET Parts guidelines without exception:
- Don't use functions as types.
- Don't use
typeof
orinstanceof
. - Don't use
new
. - Don't access a property directly.
- Don't use
{}
as a hash/dictionary. - Don't use
for/in
.
TIBET provides more powerful replacements, namely:
defineSubtype
andaddTraits
isType
,isKindOf
,isMemberOf
, etc.construct
(a pairing ofalloc
andinit
)get()
andset()
methods with dynamic method lookupTP.core.Hash
(TP.hc
) and its collection API support- TIBET's
perform
,collect
,select
,detect
,reject
, etc.
You should be familiar with TIBET Signaling and Routing as outlined here:
- TIBET Signaling (particularly responders and the responder chain)
- TIBET Routing (especially controller stack and state machine bits)
You should also read The Zen Of TIBET which discusses TIBET's design principles.
Other conventions and patterns we've found useful in creating maintainable code are outlined below. You should conform to these conventions to be successful with TIBET.
Cookbook
Files
Keep types in their own file
While not required, TIBET will work more effectively if you avoid having more
than one type per file. The TIBET CLI commands such as tibet type
will
automatically generate new files for types you create and update your
applications load package to reference these files automatically.
TIBET's rollup and packaging tools will automatically concatenate these files to avoid any extra HTTP overhead that might otherwise occur from having numerous type files.
Keep type CSS in its own file
For easier authoring it's better to keep CSS specific to a particular tag type
in a unique file named to match the type. As with many other file-level
operations the tibet type
command will automatically generate files to support
this convention.
TIBET's rollup and resource inlining tools will automatically combine these files and/or inline them to eliminate any HTTP overhead that might otherwise occur as a result of keeping your type's CSS in a separate file.
Consider using "component bundles"
To help with potentially sharing tags and other components across projects via
the tibet publish
and tibet install
commands, consider keeping all assets
and logic related to your tags in separate subdirectories of your ~app_src
directory.
Names
Use the source :)
The full TIBET library with all extensions, addons, and optional namespaces, comprises over 330k lines of heavily commented code (a 55/45 code-to-comment ratio). That's a lot of source text to draw upon for existing patterns, and names.
If you're creating new code and not sure what to name something check the existing TIBET source code. There's a lot of existing effort behind naming in the TIBET code. If at all possible try to leverage that when creating new code.
tibet reflect
and tibet apropos
are particularly useful for this purpose.
Use TIBET's method name pattern
TIBET uses a common pattern for naming functions and methods, one largely inspired by Smalltalk and Objective-C, languages which provide for reasonably "literate" API design.
The pattern is simple and relies on using the parameters to help you arrive at a method name which helps you remember what to pass where.
For example, TIBET has a collection API method atPut
. This method name is the
result of following our naming pattern, which begins with examining the
known parameters.
Our method parameters in this example consist of an index
and a value
to
place at that index. In Smalltalk/Objective-C our method would resemble
at: index put: value
.
To convert at: put:
to valid JavaScript we take the word portions
and concatenate them in camel-case form so that at: index put:
value
becomes atPut(index, value)
.
TP.core.Hash.Inst.defineMethod('atPut',
function(anIndex, aValue) {
...
});
The goal is to end up with method names that not only tell you something about
what the method does, but which also help remind you of the parameter order.
Just invert the process. If you split atPut
on word boundaries you arrive back
at at: x put: y
, which makes it easy to remember where index
and value
go.
Use TIBET's primitive name pattern
The TIBET platform uses several hundred lower-level functions to create an insulating layer between TIBET and the underlying browsers in which it runs. We call these functions "primitives" after the Smalltalk term for similar low-level C interfaces.
TIBET primitives almost universally begin with an object name in lower case, something like 'element', 'attribute', 'node', etc. which identifies the type of the first parameter. The remainder of the name tends to follow the TIBET convention for method names.
TP.definePrimitive('nodeGetDocument', function(aNode) {...});
You can use awareness of this pattern to help you find useful functionality. For any APP-level primitives you create we recommend following a similar convention.
Coding
Use the source (part deux)
One of the central tenets of TIBET is that the library should provide 80% of your functionality and you should provide the 20% specific to your application.
If you find yourself writing a lot of JavaScript it may be that we've overlooked something, but it also may be that you haven't explored the existing source thoroughly enough.
Commands like tibet apropos
and tibet reflect
can be helpful in exploring
the library for objects, methods, and primitives that may already do what you
need.
Use TIBET coding standards
See JavaScript: The TIBET Parts and TIBET Coding Standards for a detailed discussion of the baseline standards your TIBET code should follow.
In extreme form the quick summary of necessary changes is:
- Don't use functions as types.
- Don't use
typeof
orinstanceof
. - Don't use
new
. - Don't access a property directly.
- Don't use
{}
as a hash/dictionary. - Don't use
for/in
.
TIBET provides much more powerful replacements, namely:
defineSubtype
andaddTraits
isType
,isKindOf
,isMemberOf
, etc.construct
(a pairing ofalloc
andinit
)get()
andset()
methods with dynamic method lookupTP.core.Hash
(TP.hc
) and its collection API support- TIBET's
perform
,collect
,select
,detect
,reject
, etc.
Additional standards such as placing your method comments for better reflection and tooling and numerous other hints are also described in those documents.
Simplifying
Use TIBET's tools to simplify development
As a full-stack solution that includes both a full suite of command line tools and a browser-based IDE, TIBET provides you with a lot of tooling to help simplify your development.
For example, rather than creating new files yourself use the tibet type
command
to add new classes to your application. This will automatically create the new
type file with pre-built logic as well as any associated asset files such as a
default template file and style sheet. The tibet type
command will also
automatically update your application's load package to make sure the new type
is loaded correctly. If your application is running it will also automatically
patch in the new type, template, and style sheet without reloading.
Using the TIBET Lama can be even simpler. For example, creating a new tag is
as easy as drag-and-drop. After filling in a simple dialog the tibet type
command is run for you and the new assets are automatically patched into your
running application.
Use the APP
root to separate application code
Unlike other platforms, TIBET relies on a strong separation between library code and application code. This separation is leveraged in tooling, caching, and a number of other places in TIBET.
A good design pattern is to modularize between components with different rates of change. For example, you're changing your application code daily but you may only update your TIBET library once a quarter. Keeping the two separate helps reinforce not only a clean boundary of responsibility but one that can benefit you in other ways.
In TIBET, all application code is expected to be rooted on a
single global, APP
, which is provided as part of the TIBET library. TIBET's
CLI commands support this convention whenever you use them within a project
context. If you use the tibet type
command either from the CLI or via the
Lama your new type will normally be rooted off APP
.
As one example of the benefits of the APP vs. TP approach, by separating your code from the library TIBET lets you reload application code without forcing a reload of TIBET library code, dramatically reducing load times and network overhead.
Use defineHandler
to simplify event handling
One of the more powerful features of TIBET is what we call the "responder chain", the set of implicit event handlers in place for any signal which occurs.
As an example, when you click on a button in your UI TIBET will automatically
create a chain consisting of the button itself, any tibet:ctrl
on that button,
and any custom tags or controllers in the button's ancestor DOM chain. TIBET
will also automatically include your Application instance and its controller
stack in the responder chain.
The resulting responder chain is then checked, type by type, for any handler methods which are suitable given the origin of the event, the nature of the event, and the current application state. This is all handled automatically, you never have to explicitly observe or ignore individual UI elements.
Use TIBET patterns to simplify code
From get
and set
to callNextMethod
and callBestMethod
, TIBET is full of
prebuilt patterns and method lookups that can dramatically simplify coding.
Creating a new type and want to initialize it on startup? Implement initialize
.
Need to be able to build instances from hashes? Implement fromTP.core.Hash
.
Want to parse strings to create instances? Implement parse
.
TIBET pattern methods cover a wide range of functionality, usually in pairs:
- as/from
- isa/validate
- parse/format
- get/set
Leveraging these and other common TIBET methods allow your objects to fit quickly into the overall TIBET ecosystem.
Code
Look for examples of TIBET's conventions throughout the codebase.