Hubbry Logo
Go! (programming language)Go! (programming language)Main
Open search
Go! (programming language)
Community hub
Go! (programming language)
logo
7 pages, 0 posts
0 subscribers
Be the first to start a discussion here.
Be the first to start a discussion here.
Go! (programming language)
Go! (programming language)
from Wikipedia
Go!
ParadigmMulti-paradigm: concurrent, logic, functional, imperative (object-based)
Designed byFrancis McCabe, Keith Clark
First appeared2003; 22 years ago (2003)
Preview release
9-30-07 / September 30, 2007; 18 years ago (2007-09-30)
Typing disciplinestrong
OSUnix-like
LicenseGPLv2
Influenced by
Prolog[1]

Go! is an agent-based programming language in the tradition of logic-based programming languages like Prolog.[1] It was introduced in a 2003 paper by Francis McCabe and Keith Clark.[2]

Design

[edit]

The authors of Go! describe it as "a multi-paradigm programming language that is oriented to the needs of programming secure, production quality and agent-based applications. It is multi-threaded, strongly typed and higher order (in the functional programming sense). It has relation, function and action procedure definitions. Threads execute action procedures, calling functions and querying relations as needed. Threads in different agents communicate and coordinate using asynchronous messages. Threads within the same agent can also use shared dynamic relations acting as Linda-style tuple stores."[2]

The authors also propose that the language is suitable for representing ontologies due to its integration of logic, functional and imperative styles of programming.[3]

Example

[edit]

The following example illustrates the "ontology-oriented" type and declarations style of Go!:[3]

Sex ::= male | female.

person <~ {dayOfBirth:[] => day.
           age:[] => integer.
           sex:[] => Sex.
           name:[] => string.
           home:[] => string.
           lives:[string]{}}.

person:[string, day, Sex, string] $= person.

person(Nm, Born, Sx, Hm)..{
  dayOfBirth() => Born.
  age() => yearsBetween(now(), Born).
  sex() => Sx.
  name() => Nm.
  home() => Hm.
  lives(Pl) :- Pl = home().
  yearsBetween:[integer, day] => integer.
  yearsBetween(...) => ..
}.

newPerson:[string, day, Sex, string] => person.

newPerson(Nm, Born, Sx, Hm) => $person(Nm, Born, Sx, Hm).
  • The ::= rule defines a new algebraic data type, a data type with only data constructors.
  • The <~ rule defines an interface type - it indicates what properties are characteristic of a person and also gives type constraints on these properties. It documents that age is a functional property with an integer value, that lives is a unary relation over strings, and that dayOfBirth is a functional property with a value that is an object of type day.
  • The $= type rule indicates that there is also a theory label, with the functor person, for a theory that defines the characteristic properties of the person type - implements the person interface - in terms of four given parameters of types string, day , Sex, and string.

Conflict with Google

[edit]

In November 2009, Google released a similarly named Go programming language (with no exclamation point). McCabe asked Google to change the name of their language as he was concerned they were "steam-rolling over us".[1][4] The issue received attention among technology news websites, with some of them characterizing Go! as "obscure".[5] The issue thread opened on the subject was closed by a Google developer on 12 October 2010 with the custom status "Unfortunate" and with the following comment: "there are many computing products and services named Go. In the 11 months since our release, there has been minimal confusion of the two languages."[6]

References

[edit]

Further reading

[edit]
[edit]
Revisions and contributorsEdit on WikipediaRead on Wikipedia
from Grokipedia
Go! is a multi-paradigm programming language designed for developing secure, production-quality, multi-threaded agent-based applications. It integrates logic, functional, imperative, and styles, with a strong emphasis on ontology-oriented programming and concurrent agents. Developed by Keith Clark of and Francis McCabe of Labs of America, Go! was introduced in a 2003 paper and extends earlier work on languages like L&O (Logic and Objects) from 1992. The language supports strongly typed, higher-order functions and relations, with compile-time type checking using a Hindley-Milner style inference system. A key feature is its concurrency model, which uses lightweight threads (agents) that communicate via asynchronous messages to mailboxes or shared dynamic relations in a Linda-style , enabling deliberative and reactive behaviors in multi-agent systems. Go! also incorporates moded types for declarations and representation through labeled theories and inheritance, comparable to Lite for knowledge representation. Go! has influenced research in agent-oriented and ontology-based programming but remains primarily an academic and experimental language, with implementations available through archived projects. It is distinct from Google's Go (Golang) programming language, leading to a notable naming conflict upon the latter's release in 2009.

History

Origins and development

The Go! programming language originated in the early 2000s as an effort to create a specialized tool for developing secure and distributed multi-agent systems. It evolved from earlier work on the language April, which was initially developed for the EU-funded Imagine project's Multi-Agent Intelligent Intermediate Layer (MAI2L) agent programming framework. Conceptual development took place during this period at Imperial College London, where the language was designed to address limitations in existing paradigms for agent-based applications, drawing foundational influences from logic programming languages like Prolog. Go! was introduced by Keith L. Clark and Francis G. McCabe in a 2003 preprint and formally published in 2004 in their paper titled "Go! – A Multi-paradigm Programming Language for Implementing Multi-threaded Agents," published in the Annals of Mathematics and Artificial Intelligence. The paper outlined the language's core structure, emphasizing its suitability for production-quality software in agent environments. Following its conceptual inception, Go! saw practical application in the EU AgentCities project, where it supported the implementation of FIPA-compliant agent platforms and services at institutions including Imperial College and Laboratories of America. The primary motivations behind Go!'s development centered on integrating multiple programming paradigms—logic, functional, imperative, and concurrent—to enable ontology-driven programming in multi-agent systems. Creators aimed to enhance logic programming's applicability for real-world developers by incorporating strong , features, and support for multi-threaded architectures, thereby facilitating natural and robust implementations of hybrid reactive and deliberative agents in secure, distributed settings. This multi-paradigm approach was intended to promote transparency, , and adherence to best practices in agent-based applications.

Release and current status

The Go! programming language was first publicly described in a 2003 preprint by Keith Clark and Francis McCabe, with formal publication in 2004, introducing it as a multi-paradigm system for implementing multi-threaded agents. In 2007, Francis McCabe published a book on the language, . A subsequent 2006 paper expanded on its ontology-oriented aspects, demonstrating its expressiveness for knowledge representation compared to Lite. No full production release has occurred, and the language has remained in an experimental stage, with development efforts focused on prototype implementations rather than widespread adoption. An experimental implementation, including a and runtime system, is available as open-source code on under the repository maintained by Francis McCabe. The repository's initial commit dates to , with no subsequent updates recorded, indicating a halt in active development around that time or earlier. While the original prototype may have been distributed through academic channels prior to the GitHub hosting, no active downloads, official repositories, or maintained distributions are currently accessible beyond this archived code. As of November 2025, Go! remains obscure and largely unused in practice, with minimal community engagement or ongoing contributions. The 2009 release of Google's similarly named Go programming language (without the exclamation point) contributed to reduced visibility for Go!, as McCabe requested but failed to persuade Google to change their language's name, exacerbating its dormancy.

Design

Goals and paradigms

Go! was designed to facilitate the rapid development of secure, production-quality applications involving multi-threaded agents in multi-agent systems, with a strong emphasis on ontology-oriented programming to represent and manipulate knowledge domains effectively. This approach prioritizes expressiveness for and scenarios, enabling agents to model beliefs, desires, and intentions through shared, dynamic knowledge structures while avoiding vulnerabilities associated with shared mutable state. The language adopts a multi-paradigm framework that integrates concurrent agent-based programming for handling reactive and deliberative behaviors, for relation-based querying and declarative knowledge representation, higher-order for composable abstractions, and through action procedures for procedural control. Its concurrent model relies on asynchronous via mailboxes to support inter-agent communication and multi-casting, promoting and in distributed environments. Shared dynamic relations serve as a Linda-style mechanism for intra-agent coordination, allowing threads to suspend and resume based on knowledge updates without direct state sharing. Unlike pure logic languages such as —whose influence is evident in Go!'s logic aspects—Go! incorporates imperative control flows and functional composition to enable practical implementations of complex agent behaviors, including compile-time type checking and run-time constraints for robustness. This differentiation positions Go! as a rather than a purely declarative one, balancing expressiveness with the needs of secure, production-ready systems.

Ontology-oriented programming

Go! introduces ontologies as a fundamental construct for knowledge representation, enabling developers to define classes with associated properties, relations, and hierarchies to model semantic domains declaratively. An ontology in Go! serves as a labeled that characterizes a domain, where classes such as "" are specified with functional properties (e.g., dayOfBirth mapping to a day type) and relational properties (e.g., livesIn linking to locations), supporting both static typing and dynamic extensions. is achieved through subclassing mechanisms, allowing derived classes like "" to extend base ontologies such as "" while inheriting and refining their attributes. This ontology system integrates seamlessly with Go!'s logic programming foundations, transforming ontologies into declarative knowledge bases that support queries and inferences akin to those in . Developers can query ontology instances using logic-based patterns, such as retrieving names and ages of persons satisfying certain conditions, with inferences derived from rules embedded within the ontology definitions. Unlike purely declarative ontology languages, Go! extends this with procedural elements, including action rules that trigger imperative computations during inference, enabling hybrid reasoning over knowledge bases. For agent-oriented applications, Go!'s ontologies facilitate the creation of dynamic, shared models that multiple agents can access and update securely. By enforcing type constraints at and supporting dynamic relations for extensible belief stores, ontologies ensure that information exchange between agents adheres to predefined semantic structures, reducing errors in distributed systems. This approach promotes in multi-agent environments, where agents can reason over shared ontologies without exposing internal state. Compared to the (OWL), particularly OWL Lite, Go! ontologies provide greater expressiveness for programming tasks through their embedding of and imperative actions, though they are less formally rigorous for standalone ontological specifications. While OWL focuses on declarative descriptions with restrictions on properties and classes, Go! supports n-ary relations, runtime constraints, and procedural extensions like computed properties (e.g., deriving age from birth date), making it more suitable for implementing active knowledge systems. This hybrid nature allows Go! to bridge semantic modeling with executable code, surpassing OWL's limitations in handling dynamic, programmatic inferences.

Features

Type system and relations

Go! employs a strong, static that performs compile-time type checking using a modified Hindley-Milner style mechanism, ensuring across multi-agent interactions by requiring explicit type declarations for variables and supporting polymorphic higher-order functions and closures. This ontology-based typing integrates class-like theories as foundational type definitions, where theories specify structured knowledge representations with inheritance and constraints, allowing objects—instances of these theories—to adhere to semantic rules during agent communication and data exchange. For instance, type declarations can define enumerated types or constructors, such as type macro sex ::= male | female, which propagate through the program to prevent type mismatches in distributed environments. A core feature of Go!'s type system is its support for dynamic relations, which serve as shared, updatable fact bases for storing and managing relational data without relying on traditional mutable state variables. Relations are declared using syntax like relation Person(dayOfBirth: Date, age: Integer), where parameters are typed to enforce consistency, and instances are created as objects of type dynamic[T], supporting operations such as add, del, and mem for tuple-based storage. These relations enable declarative knowledge representation, akin to frames in ontology languages, and are particularly suited for multi-threaded agents by allowing atomic updates and shared access without explicit locking primitives. Querying over these relations employs a logic-style mechanism with unification and , integrated seamlessly with functional mappings to compute derived facts or filter data. For example, a query like { (P.name, Yr, P.home) || a_person(P) } uses set comprehension with unification to bind variables against relation facts, while handles multiple solutions via Prolog-inspired clauses such as takes_only_maths_courses(S:student) :- (S.takes(C:course) *> C.subject='maths'). Functional aspects enhance this by defining computed attributes through rewrite rules, like age() => yearsBetween(now(), born), which can be invoked within relational queries to blend imperative computation with logical inference. This combination ensures type-safe, efficient data retrieval in -driven applications, reducing errors in agent-based reasoning.

Concurrency and agent model

Go! supports concurrent execution through an , where programs are structured as autonomous agents that encapsulate private state and interact via asynchronous . Each agent consists of one or more threads that implement distinct behaviors, such as or execution, while sharing internal dynamic relations to manage beliefs, desires, and intentions without exposing mutable state externally. This design draws from the BDI (Beliefs-Desires-Intentions) architecture, enabling hybrid reactive and deliberative agents suitable for intelligent applications. For instance, a "dancer" agent might employ separate threads for handling directory interfaces, conducting s, and executing intentions, coordinating through shared relation stores. The messaging system in Go! facilitates non-blocking sends and receives to promote safe concurrency, eschewing shared mutable state across agents to eliminate race conditions. Messages are dispatched asynchronously using syntax like Msg >> To, where sends complete immediately without blocking the sender, while receives (Ptn << From) suspend the receiving thread until a matching message arrives, akin to pattern-matching in Erlang. Inter-agent communication relies exclusively on this mailbox-based mechanism, with mailboxes acting as queues that multiple threads can write to but typically only one reads from. Within an agent, threads may share dynamic relations as blackboard-style memory, but external interactions remain message-only to enforce encapsulation and prevent unintended interference. Action procedures form the core of reactive behavior, defined as imperative code blocks triggered by incoming messages or environmental events, often combined with logic queries for decision-making. These procedures follow rules of the form a(A1,...,Ak)::Test -> Action1; ...; Actionn, where a test (potentially involving Prolog-style queries over relations) guards a of actions such as I/O operations, relation updates, or spawning new threads. For example, a thread might react to a "starting" from a band announcement with starting(D) << band -> add_intention(perform(D)), querying intentions via forall operators (*>) to select appropriate responses. This integration allows agents to respond dynamically while maintaining logical consistency. The concurrency model emphasizes security for distributed systems, where agents may operate in untrusted environments across multiple invocations of the Go! runtime. By confining mutable state to private dynamic relations and restricting inter-agent data exchange to typed, asynchronous messages, the language mitigates risks like unauthorized access or corruption. Relations serve as a safe sharing mechanism internally, supporting tuple-space-like operations (inspired by Linda) without direct memory access, thus promoting integrity and transparency in production-quality, high-assurance applications.

Syntax and examples

Basic syntax overview

Go! employs a declarative style for defining ontologies and relations, drawing inspiration from logic programming languages like . Ontologies are specified using interface types with the <~ operator to declare classes and their properties, such as person <~ { name:[]=>string; age:[]=>int }, where properties are typed as functions returning specific types. Relations, which represent multi-valued or dynamic associations, are defined using Prolog-style clauses with the :- operator for rules, for example, livesIn(Person, Place) :- Person.home() = Place, and are typed with a signature like livesIn:[person, place] {} to indicate input and output modes. The language's logic query syntax supports and unification through capitalized variables in relation calls and set comprehensions, enabling queries like { Child || Parent.child(Child) } to retrieve all children of a parent via implicit unification of terms. Functions are declared with rewrite rules using the :: guard followed by => for the expression, as in numberOfChildren(P):: => len({ C || P.child(C) }), typed as [person]=>int, allowing compositional use in expressions without explicit syntax, though higher-order behavior can be simulated via object methods. Imperative elements appear in action definitions, which handle side effects and are typed with an suffix, such as display(P):[person]*, using -> to sequence statements with semicolons, like display(P) -> stdout.outLine(P.name()); P.age() > 18 -> .... relies on constructs like case for conditional branching, equivalent to , while loops are absent, favoring in functions or iterative queries in relations for repetition.

Code examples

To illustrate the practical application of Go!'s syntax and features, consider a basic declaration for a person entity. This example defines an interface specifying properties such as birth date and computed age, followed by a theory that implements these properties, an instance creation, and a simple query to retrieve the age. The interface declares the expected methods without :

person <~ { dayOfBirth:[]=>date, age:[]=>[integer](/page/Integer), name:[]=>[symbol](/page/Symbol), home:[]=>[string](/page/String) }.

person <~ { dayOfBirth:[]=>date, age:[]=>[integer](/page/Integer), name:[]=>[symbol](/page/Symbol), home:[]=>[string](/page/String) }.

A then provides a concrete , including a function to compute age based on the current date:

person(Nm:[symbol](/page/Symbol), Born:date, Sx:[symbol](/page/Symbol), Hm:[string](/page/String)).. { dayOfBirth() => Born. age() => yearsBetween(now(), Born). name() => Nm. home() => Hm. }.

person(Nm:[symbol](/page/Symbol), Born:date, Sx:[symbol](/page/Symbol), Hm:[string](/page/String)).. { dayOfBirth() => Born. age() => yearsBetween(now(), Born). name() => Nm. home() => Hm. }.

An instance can be created using constructor notation:

P = $person('Alice', date(1990, 5, 15), 'female', 'New York').

P = $person('Alice', date(1990, 5, 15), 'female', 'New York').

Executing the query P.age() would return the integer difference in years from the birth date to the present, such as 35 if run in 2025. This demonstrates Go!'s integration of declarative definitions with functional computation, where the yearsBetween function handles the . For a more advanced illustration, consider agent interactions in a multi-threaded , such as a simplified among agents using asynchronous to update and query shared relations. Go! agents communicate via mailboxes with non-blocking sends (>>) and pattern-matched receives (<<), enabling concurrent deliberation. This example draws from a dancer agent model where agents maintain dynamic relations for beliefs, desires, and intentions, updating them collaboratively to match partners. A shared Linda-style relation for desires might be declared as:

desire:[term] {}.

desire:[term] {}.

An agent thread could send a desire to dance and await responses:

thread { desire.add(toDance('waltz', 2)). 'request' >> PartnerMailbox. Msg << Partner -> case Msg in ('accept' -> desire.del(toDance(_,2)); partner=Partner | 'reject' -> true). }.

thread { desire.add(toDance('waltz', 2)). 'request' >> PartnerMailbox. Msg << Partner -> case Msg in ('accept' -> desire.del(toDance(_,2)); partner=Partner | 'reject' -> true). }.

Another agent receives the message and queries/updates its own desires:

thread { 'request' << Sender -> desire.mem(toDance('waltz',2)) -> 'accept' >> Sender; desire.del(toDance('waltz',2)); belief.add(pairedWith(Sender)). | 'reject' >> Sender. }.

thread { 'request' << Sender -> desire.mem(toDance('waltz',2)) -> 'accept' >> Sender; desire.del(toDance('waltz',2)); belief.add(pairedWith(Sender)). | 'reject' >> Sender. }.

A query across agents might then check for successful pairings: { Partner || belief.mem(pairedWith(Partner)) }. This showcases for coordination, where updates to shared relations like desire propagate asynchronously, and queries use set comprehensions to aggregate results from logic relations. Execution involves deterministic matching for functions and relations (without traditional Prolog-style in selection), but asynchronous threads allow non-deterministic concurrency via mailbox queuing and choice constructs. These examples are derived from the language specifications and associated publications from the early . An implementation of Go! was released under the GNU General Public License and is available for download from (project "Network Agents", last updated in 2013), though it may require adaptation for modern systems as of 2025. Execution is thus possible but limited to this legacy version.

Reception and legacy

Naming conflict with Google Go

On November 10, 2009, coinciding with 's public announcement of its new programming language named Go, Francis McCabe, the primary developer of the existing Go! language, filed Issue #9 on the project's Google Code tracker, requesting that Google rename its language to prevent confusion. McCabe noted that he had been developing Go! for approximately ten years, with key publications including a 2003 academic paper introducing its agent-based features and a 2007 book detailing its logic-oriented design. The filing sparked significant discussion in developer communities, with over 120 supporters advocating for a rename and some accusing of violating its "" motto by potentially overshadowing the lesser-known Go!. Google's initial response, provided through a , acknowledged awareness of the existing Go! and stated that the company was investigating the matter further. However, nearly a year later, on October 12, 2010, Go team member Russ Cox closed the issue without altering the name, reasoning that the risk of confusion was very low given the distinct natures of the languages—Go!'s emphasis on agent-based, versus Google's focus on efficient —as well as orthographic differences like the in Go! and separate project domains (golang.org for Google's Go). Ultimately, neither language underwent a , leaving both to coexist under similar monikers. This outcome underscored broader challenges in naming conventions for programming languages, including the absence of centralized oversight and the potential for larger entities to dominate visibility. In practice, the dispute amplified concerns about in open-source ecosystems but resulted in no formal legal action. The naming conflict has had lasting implications for Go!, contributing to its relative obscurity as Google's Go gained widespread adoption and search engine prominence; queries for "Go programming language" overwhelmingly prioritize results for the Google version, often relegating Go! to niche or historical mentions.

Influence and availability

Go! pioneered ontology-oriented programming within logic-based languages by embedding ontological structures—such as classes, subclasses, and relations—directly into its type system and labeled theories, enabling seamless integration of knowledge representation with executable code. This innovation extended earlier work in logic and objects, providing a foundation for expressing -like semantics in a programmable form more expressive than OWL Lite for rule-based reasoning. The language's design has influenced tools. In multi-agent systems frameworks, Go!'s emphasis on secure, multi-threaded agents with transparent concurrency has inspired approaches to agent communication and distributed reasoning, as seen in FIPA-compliant platforms. Compared to Prolog, which focuses on declarative logic programming without built-in support for agents or objects, Go! is distinctly agent-oriented, combining logic rules with imperative control, functional expressions, and multi-threading to facilitate real-world agent behaviors like negotiation and coordination. Despite these advances, Go! has experienced significantly less adoption than contemporary logic languages such as Mercury, which prioritizes performance via mode and type analysis for industrial applications, or miniKanren, an embedded domain-specific language favored for its minimalism in relational and search-based programming. The 2009 release of Google's Go programming language exacerbated visibility issues, as the naming overlap dominated search results and community discussions, further limiting Go!'s reach. As of 2025, Go! maintains no active development community or contemporary tools, with its prototype implementation archived on under the GNU General Public License as part of the Network Agents project, last updated in 2013. Preview code examples and documentation remain accessible through academic repositories, including PDFs hosted by detailing its syntax and agent applications. Go!'s legacy underscores the barriers to widespread use for niche, paradigm-blending languages, particularly in balancing expressiveness with practicality, yet it endures as a cited reference in scholarly works on hybrid ontologies, semantic , and agent-oriented paradigms. With approximately 50 citations across platforms like , its contributions highlight early explorations in ontology-driven development without achieving broad implementation.
Add your contribution
Related Hubs
User Avatar
No comments yet.