Recent from talks
Nothing was collected or created yet.
Go! (programming language)
View on Wikipedia| Go! | |
|---|---|
| Paradigm | Multi-paradigm: concurrent, logic, functional, imperative (object-based) |
| Designed by | Francis McCabe, Keith Clark |
| First appeared | 2003 |
| Preview release | 9-30-07
/ September 30, 2007 |
| Typing discipline | strong |
| OS | Unix-like |
| License | GPLv2 |
| 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 apersonand also gives type constraints on these properties. It documents thatageis a functional property with an integer value, thatlivesis a unary relation over strings, and thatdayOfBirthis a functional property with a value that is an object of typeday. - The
$=type rule indicates that there is also a theory label, with the functorperson, for a theory that defines the characteristic properties of thepersontype - implements thepersoninterface - in terms of four given parameters of typesstring,day,Sex, andstring.
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]- ^ a b c Claburn, Thomas (2009-11-11). "Google 'Go' Name Brings Accusations Of 'Evil'". InformationWeek. Archived from the original on 2010-07-22. Retrieved 2009-11-14.
- ^ a b Clark, K.L.; McCabe, F.G. (2003). "Go! For multi-threaded deliberative agents". Proceedings of the second international joint conference on Autonomous agents and multiagent systems. pp. 964–965. CiteSeerX 10.1.1.117.184. doi:10.1145/860575.860747. ISBN 978-1581136838. S2CID 2047545.
- ^ a b Clark, K. L.; McCabe, F. G. (2006). "Ontology oriented programming in go!". Applied Intelligence. 24 (3): 189–204. doi:10.1007/s10489-006-8511-x.
- ^ "Issue 9 - go - I have already used the name for *MY* programming language". 2009-11-10. Retrieved 2009-11-14.
- ^ Brownlee, John (2009-11-13). "Google didn't google "Go" before naming their programming language". Geek.com. Archived from the original on 2012-05-06. Retrieved 2010-01-18.
- ^ "I have already used the name for *MY* programming language · Issue #9 · golang/go". GitHub. Retrieved 2019-07-04.
Further reading
[edit]- Clark, K. L.; McCabe, F. G. (2003). "Ontology Oriented Programming in Go!" (PDF).
- Clark, K. L.; McCabe, F. G. (2004). "Go!—A Multi-Paradigm Programming Language for Implementing Multi-Threaded Agents". Annals of Mathematics and Artificial Intelligence. 41 (2–4): 171–206. CiteSeerX 10.1.1.133.1069. doi:10.1023/B:AMAI.0000031195.87297.d9. S2CID 6992205.
- R. Bordini; et al. (2006). "A Survey of Programming Languages and Platforms for Multi-Agent Systems". Informatica. 30: 33–44. Archived from the original on 2009-11-15.
- M. Fisher; et al. (2007). "Computational Logics and Agents - A Roadmap of Current Technologies and Future Trends". Computational Intelligence. 23 (1): 61–91. CiteSeerX 10.1.1.114.6149. doi:10.1111/j.1467-8640.2007.00295.x. S2CID 3393868. Archived from the original on 2013-01-06.
- McCabe, Francis G. (February 7, 2007). Lets Go!. Network Agent Press. ISBN 978-0-9754449-1-7.
- C. Varela; et al. (2004). On Modelling Agent Systems with Erlang. ACM SIGPLAN Erlang Workshop '04. Archived from the original on 2009-11-15. Retrieved 2009-11-12.
External links
[edit]Go! (programming language)
View on GrokipediaHistory
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.[4] 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.[4] 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.[5] 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 Fujitsu Laboratories of America.[4] 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.[5] Creators aimed to enhance logic programming's applicability for real-world developers by incorporating strong typing, security features, and support for multi-threaded architectures, thereby facilitating natural and robust implementations of hybrid reactive and deliberative agents in secure, distributed settings.[4] This multi-paradigm approach was intended to promote transparency, integrity, and adherence to software engineering best practices in agent-based applications.[5]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.[5] In 2007, Francis McCabe published a book on the language, Go!: A Multi-Paradigm Language for Implementing Multi-threaded Agents.[6] A subsequent 2006 paper expanded on its ontology-oriented aspects, demonstrating its expressiveness for knowledge representation compared to OWL Lite.[7] 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.[2] An experimental implementation, including a compiler and runtime system, is available as open-source code on GitHub under the repository maintained by Francis McCabe.[8] The repository's initial commit dates to 2015, 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.[8] 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.[3]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.[4] This approach prioritizes expressiveness for artificial intelligence and distributed computing scenarios, enabling agents to model beliefs, desires, and intentions through shared, dynamic knowledge structures while avoiding vulnerabilities associated with shared mutable state.[2] The language adopts a multi-paradigm framework that integrates concurrent agent-based programming for handling reactive and deliberative behaviors, logic programming for relation-based querying and declarative knowledge representation, higher-order functional programming for composable abstractions, and imperative programming through action procedures for procedural control.[4] Its concurrent model relies on asynchronous message passing via mailboxes to support inter-agent communication and multi-casting, promoting loose coupling and scalability in distributed environments.[4] Shared dynamic relations serve as a Linda-style tuple space mechanism for intra-agent coordination, allowing threads to suspend and resume based on knowledge updates without direct state sharing.[4] Unlike pure logic languages such as Prolog—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.[2] This differentiation positions Go! as a general-purpose language rather than a purely declarative one, balancing expressiveness with the needs of secure, production-ready systems.[2]Ontology-oriented programming
Go! introduces ontologies as a fundamental construct for knowledge representation, enabling developers to define classes with associated properties, relations, and inheritance hierarchies to model semantic domains declaratively.[2] An ontology in Go! serves as a labeled theory that characterizes a knowledge domain, where classes such as "person" 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.[2] Inheritance is achieved through subclassing mechanisms, allowing derived classes like "student" to extend base ontologies such as "person" while inheriting and refining their attributes.[2] 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 description logics.[2] 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.[2] 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.[2] For agent-oriented applications, Go!'s ontologies facilitate the creation of dynamic, shared knowledge models that multiple agents can access and update securely.[2] By enforcing type constraints at compile time 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.[2] This approach promotes interoperability in multi-agent environments, where agents can reason over shared ontologies without exposing internal state.[2] Compared to the Web Ontology Language (OWL), particularly OWL Lite, Go! ontologies provide greater expressiveness for programming tasks through their embedding of logic programming and imperative actions, though they are less formally rigorous for standalone ontological specifications.[2] 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.[2] This hybrid nature allows Go! to bridge semantic modeling with executable code, surpassing OWL's limitations in handling dynamic, programmatic inferences.[2]Features
Type system and relations
Go! employs a strong, static type system that performs compile-time type checking using a modified Hindley-Milner style type inference mechanism, ensuring type safety across multi-agent interactions by requiring explicit type declarations for variables and supporting polymorphic higher-order functions and closures.[4] 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.[9] For instance, type declarations can define enumerated types or constructors, such astype macro sex ::= male | female, which propagate through the program to prevent type mismatches in distributed environments.[9]
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.[4] 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.[9] 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.[4]
Querying over these relations employs a logic-style mechanism with unification and backtracking, integrated seamlessly with functional mappings to compute derived facts or filter data.[9] 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 backtracking handles multiple solutions via Prolog-inspired clauses such as takes_only_maths_courses(S:student) :- (S.takes(C:course) *> C.subject='maths').[9] 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.[4] This combination ensures type-safe, efficient data retrieval in ontology-driven applications, reducing errors in agent-based reasoning.[9]
Concurrency and agent model
Go! supports concurrent execution through an agent-based model, where programs are structured as autonomous agents that encapsulate private state and interact via asynchronous message passing. Each agent consists of one or more threads that implement distinct behaviors, such as negotiation 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 negotiations, and executing intentions, coordinating through shared relation stores.[10] 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 likeMsg >> 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.[10]
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 sequence of actions such as I/O operations, relation updates, or spawning new threads. For example, a thread might react to a "starting" message 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.[10]
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.[10]
Syntax and examples
Basic syntax overview
Go! employs a declarative style for defining ontologies and relations, drawing inspiration from logic programming languages like Prolog. 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.[2] 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.[7]
The language's logic query syntax supports pattern matching 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.[2] 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 lambda syntax, though higher-order behavior can be simulated via object methods.[7]
Imperative elements appear in action definitions, which handle side effects and are typed with an asterisk suffix, such as display(P):[person]*, using -> to sequence statements with semicolons, like display(P) -> stdout.outLine(P.name()); P.age() > 18 -> .... Control flow relies on constructs like case for conditional branching, equivalent to if-then-else, while loops are absent, favoring recursion in functions or iterative queries in relations for repetition.[2]
Code examples
To illustrate the practical application of Go!'s syntax and features, consider a basic ontology declaration for aperson 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.[9]
The interface declares the expected methods without implementation:
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) }.
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.
}.
P = $person('Alice', date(1990, 5, 15), 'female', 'New York').
P = $person('Alice', date(1990, 5, 15), 'female', 'New York').
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 ontology definitions with functional computation, where the yearsBetween function handles the temporal logic.[9]
For a more advanced illustration, consider agent interactions in a multi-threaded scenario, such as a simplified dance negotiation among agents using asynchronous message passing 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.[4]
A shared Linda-style relation for desires might be declared as:
desire:[term] {}.
desire:[term] {}.
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).
}.
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.
}.
{ Partner || belief.mem(pairedWith(Partner)) }. This showcases message passing 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 backtracking in selection), but asynchronous threads allow non-deterministic concurrency via mailbox queuing and choice constructs.[4]
These examples are derived from the language specifications and associated publications from the early 2000s. An implementation of Go! was released under the GNU General Public License and is available for download from SourceForge (project "Network Agents", last updated in 2013)[11], though it may require adaptation for modern systems as of 2025. Execution is thus possible but limited to this legacy version.[4]
