Skip to content
cosmos-lang edited this page Feb 23, 2023 · 26 revisions

As a logic language

Cosmos could be seen as a modern logic programming (LP) language.

In doing so, it aims to make logic programming easy by providing a variety of syntax sugar and utilities including,

  • Modules.
  • Types and better error-checking.
  • Functional programming (closures, higher-order relations).

In fact, we make use of advances in functional and logic languages. There's even support for a procedural style of programming.

Do I need to know Prolog to use the Cosmos™ programming language?

No.

As Prolog is an early logic language, a comparison is (perhaps?) hard to avoid. In practice they're quite different languages with different conventions and syntax. However, if you're not interested, you're free to skip this section. We'll try to restrict language comparisons to the respective pages.

Syntax

As a point of comparison,

human(socrates).
human(aristotle).

mortal(x) <-
    human(x).

See Cosmos code below.

rel human(x)
    x='socrates' or x='aristotle'
	
rel mortal(x)
    human(x)

DB-like programming

Note that while we lose the ability to define simple facts like human(socrates) in the same way, complex relations remain largely the same.

As a matter of fact, even in Prolog most programs will not boil down to atomic facts. A lot of them will even use operators like ->; or ;. This is an area where we excel. It's much easier to nest operators or even switch the order of statements in this syntax.

There might be a niche for DB-like programming and yet at the same time we have relations like concat which are closer to regular programming and not in any way DB-like.

Such DB-like programming can still be implemented in a number of ways, although we don't believe it should be the sole focus of such a general-purpose language. In that sense, our languages don't differ much. Languages like Datalog put more focus on databases.

All in all,

  • Use of modern strings is to be preferred (as in, more natural) than atoms. Whether a Prolog has modern strings depends on implementation.
  • Whitespace makes moving clauses around and use of complex operators easier.
  • DB-like programming is more-or-less just as supported.

A transpiler

Cosmos is currently compiled to Prolog itself. Thus, it's a "transpiler" language.

Prolog is a language that heavily benefits from a transpiler.

rel fact(x,y)
	if(x=0)
		y=1
	else
		y=x*fact(x-1)

Let's take a simple factorial relation.

The above code automatically makes use of constraint logic programming and the reified if optimization, both of which are rather recent additions to LP.

A beginner programmer would have to know about each beforehand and load both libraries accordingly. Without prior knowledge and simply using the base language, it's very likely the code would be simply wrong. It's easy to commit any number of mistakes in a simple factorial.

It's not impossible to use the language simply as a transpiler to Prolog. It compiles to a pure part of the language--it's so to speak a "Prolog, the good parts". This is because, although this is technically up to change, Prolog is currently used as a host language.

Pure by default

This is also a good example of our pure-by-default philosophy. Code written in Cosmos is expected to be pure-by-default. What this means is that code written in the language should be pure (in the sense of pure logic programming) unless you go out of the way to make it impure instead of the reverse. In the factorial example, you don't need to load any libraries to make the code pure.

Reducing the amount of impure relations in the core language is currently a work-in-progress.

Common criticisms

Before making this language, we did a survey on common criticisms of the language Prolog and we of course address them to our capability. Some criticisms may seem subjective; however, they're still a result of our survey on common criticisms. Often, the opinion is held by Prolog programmers themselves.

Upper and lowercase variables

Too many variables

Need to use extra-logical operators when falling back from the paradigm

Infinite loops hinder the logical aspect of the language

The first is an interesting albeit subjective criticism. Prolog is an old language and as such many syntactic choices like variables being uppercase did not get adopted by programming at large. While subjective, this hints to the endemic problem low usability of Prolog-like languages. In particular, our criteria for usability includes both familiarity and simplicity.

Our exploration of logic programming more-or-less relies on the assumption that a lot of the problem users have with LP languages is simply low-usability. The relation for concatenating lists is append and not as expected concat or list_concat. An implementation that tries to catch up to this will at most have both-keeping the first for backward-compatibility. The result then is that the core library is bigger than it needs to be. Even though it's huge, a relation any scripting language with a minimal library has might easily not be there. If it's-you'll find it has been added only recently. This at least shows they're aware of the issue, but doesn't change that it's an issue-otherwise they wouldn't be fixing it.

A paper-I unfortunately forgot which- mentions an implementation that didn't have a predicate for subtraction. The reason being the predicate of addition did subtraction too! This kind of mentality is still had by users of the language. Why have a commonly-used predicate when another does the job?

Logic programs often need a lot of variables, making them a tad verbose. This sums up the second criticism.

A lot of our introduced syntax sugar has the effect of decreasing the amount of variables.

x=double(double(2))

This may shorten the code,

double(2,x1)
double(x1,x)

This is also one use of our procedural-style features.

rel p(init x,x)
 if(x=2)
  next x=1
 else
  q(x)

Initializing a variable at the header is uncommon in procedural languages, though it fits into the style of most logic-based languages.

Compare to,

rel p(x,x2)
 if(x=2)
  x2=1
 else
  q(x)
  x2=x

Some may prefer using our pseudo-imperative syntax to avoid creating a x2 variable.

Another criticism is the perhaps excessive use of extra-logical operators. Such operators are generally considered to stray away from pure logic programming.

Cosmos provides a better facility for when one wants to leave the logic paradigm in the form of functions. Any non-logic programmer is already familiar the idea of a function. Thus, it's a very readable abstraction. In addition to that, functions exist in logic, so we're not straying from logic programming as much as one would think.

fun fact(x,y)
	if(x=0)
		y=1
	else
		y=x*fact(x-1)

A cut operator may be compared to goto. While a control structure such as if still deep down makes use of goto, it's usually considered a better abstraction. A procedural programmer thus favors using if-stms and while-stms. Similarly, functions could be used a better abstraction than raw non-logical operators. Of course, it's also our aim to provide ways to use pure relations effective, which by itself reduces the need for non-logical operators.

Finally, it's considered a criticism of the logic paradigm that the possibility of an infinite loop exists in otherwise logical code. However, this is simply not avoidable for any programming language. The same is true for functional programming.

is/2

The Prolog is predicate is another symptom of low usability in the language.

  • From a didactic perspective, an user is told that = is the predicate for equality. You then have an is predicate along with the = predicate.
  • It increases the amount of global operators, which we want to avoid as a minimalist language.
  • At the same time, it obfuscates what we're really doing-using functors as arithmetics. If you really wanted to do that, the code below is enough. The intent is clearer and we avoid having an extra operator with special syntax.
functor(Add, Functor)

calc(Add(1,2),z) //calc is a custom-made predicate 
print(z) //3
  • It has the side effect of making 1+1=2 a valid result.

Suffice to say, there are many reasons to deprecate the above operator.

It's not Prolog!

Any Prolog users should be aware this is not intended nor meant to be a carbon copy of Prolog as should be obvious by now. If any comparison is being made, it refers to the non-deterministic depth-first search that the language is known for. Prolog is also a tree-processing language.

For example, in Prolog the addition operator is a functor while in Cosmos it's treated as a predicate. This is what led to is/2 above and may have made some sense in the context of a tree-processing language-though not as a logic language.

Therefore, it should be emphasized that they're different languages. Cosmos focuses on using pure logic programming (as in, for example, miniKanren) in the context of high-level general-purpose scripting.

Simply copying ISO-Prolog would actually bring a number issues and misses the whole point of the language. This is shown in our practical example above. As a new language that's not bound by backward-compatibility, we can give any meaning we want to our if and not operators so as to explore pure logic programming. We'd also rather name our relation concat which is in line with a wider range of languages than stick with append, etc. As a multi-paradigm language, expecting us to favor ISO-Prolog actually makes no sense. It's akin to expecting our language to conform to ISO-Pascal. It makes no sense at all.

Being usable as a Prolog alternative to an extent is definitely part of it, but that's not all there is to the language. It has its own philosophy, syntax, multiple paradigms and there are influences from other languages aswell. It's also not going to replace Prolog in historical value, etc.

Clearly, it's our hope that a core library with increased focus on purity would provide a better basis for a logic language. Together with a changed syntax and multi-paradigm features, this might bring some life to logic programming.

Experimental

Cosmos is an extremely experimental language. In particular, one is aware there may be costs to some of the features. Like objects, first-class modules have a performance cost. There are many aspects that may warrant further investigation.

However, simply removing every feature that looks off might likewise ruin many potential uses for the language.

Finally, we're looking for contributors. You may for example send fixes to any issues you find through pastebin in the git discussion.

Cosmos is not actually backed by any big or small corporations.

If there's no contribution, it may not develop as quickly.