The Smojo Story

The Smojo programming language is the secret sauce behind our success with Autocaffe.

A lack of syntax, transformations instead of loops, the ability to create domain specific languages and the Smojo Cloud for sharing and compute combine to make it a very productive language for AI and data processing.

Smojo began as a hobby project for one of us (Arnold) while on holiday in 2010. The goal was to get his 6-year old programming. This hobby eventually morphed into Smojo.

Today, we use Smojo daily for all sorts of things, including writing Autocaffe and our AI programs. We are constantly expanding Smojo's applications, including an upcoming Smojo-to-C compiler.

Smojo's Syntax

At its heart, Smojo's syntax is borrowed from Forth, a language popular in the 1980's with school children and hobbyists.

In Smojo, everything is either a Literal (numbers, text, etc.) or a Word - it performs an action of some kind. For example, the program:

"Hello, World" .

feeds the computer the literal text "Hello, World" then prints it to the console using the word .

You can create new words in Smojo using the words : and ; These are not punctuation, they are words, so they perform an action each. For example, we can create a new word then use it.

	: hello 
		"Hello, World" .
	;
	
	hello \ this runs the hello word.

In Smojo, everything is performed from left-to-right.

This frees Smojo from tabs, brackets, semicolons and other punctuation that pervades other programming languages.

Get introduced to Smojo

Slow & easy introduction to Smojo: Comprehensive and easy enough for children. Has quizzes with answers.

Crash course for the impatient (pdf): Covers the basics. Should take about an hour.

Data structures, lazy sequences, HOFs etc. (pdf): With the crash course, covers all the ground needed for most day-to-day programming. Should take a few hours of study.

You need a free Autocaffe account to try the examples.

Transformations instead of Loops

Suppose you want to find the first 100 squares divisible by 365. How would you do this? A simple solution would be to:
  1. Take the set of integers, 1,2...
  2. Square them to get 2,4...
  3. Filter out numbers not divisible by 365
  4. Take just the first 100 elements.
  5. Print this list.

Simple right?

It's just four transformations applied one after the other starting with the integers:

	1 2 ... square 365 div?
	    100 take .list

This way of programming has a number of benefits:

Here's a similar solution using Python's loops:

	n, m = 0,1
	while (n < 100):
		x = m**2
		if (x % 365 == 0):
			print(x)
			n += 1
		 m += 1

In this code, the style of programming is very different. Because we use loops:

So, the "usual" way of doing things results in longer code and much harder to write.

Here's another puzzle: We want to print out the kth square divisible by 365, divided by the kth cube divisible by 47. Let's say we print out the first 100 of these numbers.

As before, the solution is straightforward:

  1. Find the sequence of squares as before (numerators)
  2. Similarly find the sequence of cubes (denominators)
  3. Divide them element-by-element, to get the list of answers.
  4. Take the first 100 elements.
  5. Print this list.
Here's a solution in Smojo with the transformation style of programming.

	1 2 ... square 365 div?
	1 2 ... cube 47 div?
		' \. zipwith
   	 100 take .list

We encourage you to write a program to solve this puzzle using loops in any programming language you're familiar with.

Here is a solution using loops in Python:

	i,j,n,d = 1,1,1,1
	for _ in range(100):
		while (n % 365 != 0):
		    i += 1
		    n = i ** 2
		while (d % 47 != 0):
		    j += 1
		    d = j ** 3
		print(n / d)
		n += 1
		d += 1

The logic behind this program should be obvious to most programmers, including the need for the small hack incrementing n and d at the end.

It is our belief that even this simple Python program is well beyond the ability of most non-programmers (those who don't program regularly).

The transformational approach we often use in Smojo on the other hand is very easy to understand and to apply.

Domain Specific Languages

Smojo is designed to simplify the creation of domain specific languages (DSLs). A DSL is:

You can do both in Smojo. Smojo's macros are more like Lisp's.

The purpose of the a DSL is to make specific aspects of programming much easier for non-programmers or casual users.

For example, a simple DSL we use in Autocaffe are "selectors" which simplify timeseries data windowing and feature engineering:

	: transform
	  \ --- ACTUALS ---
	   A:5   \ label , T+5
           A:0   \ y0
	
          \ ---  FEATURES  --- 
	   A:0:-30 difference  { xs } 
	   xs 
	   xs momentum
	   xs force
	;

The selector A:0:-30 means "select data from the present (T+0) to 30 steps in the past from Column A". Selectors and other changes in syntax are easily done in Smojo.

We could have instead used regular Smojo, eg: "A" 0 -30 select but this is much more verbose. Not a problem for programmers but harder for non-programmers.

Selectors are a simple example of a DSL. A more complicated example comes from our Chatbot framework. This uses DSLs to allow users to express template matching rules.

	Q: :first What is your name
	Q: :first What's your name
	Q: :first Who are you
	A: I am ${ bot-name } ; My name is ${ bot-name }
	--

	Q: :first @thank
	A: You're welcome
	--

	Q: @bye
	A: Bye ; Hear from you again ; Good bye! 
	--
This is actual Smojo code. We've just used a DSL to hammer Smojo into a shape to better express template matching rules for chatbots.

It is important to note that these template matching rules are also Smojo code. You can (and often should) mix "regular" Smojo code with your DSLs. This mixing makes DSLs in Smojo capable of doing far more than a standalone DSL.

The end result is to empower non-programmers to do what they are unlikely accomplish before.

The Smojo Cloud

Smojo is a cloud-centric language. This means it comes with a cloud baked into the language. This is useful because it can greatly simplify programming through sharing.

If you are a programmer, think about when you last compiled some open source code from scratch. Most likely, you installed it using a package installer (eg, "pip install" (Python) or "apt get" (Debian/Ubuntu) etc.), or downloaded some software library (a jar file or Ruby gem etc.)

Smojo takes this to a new level. Any Smojo programmer can publish:

Autocaffe was built on this foundation. For example, suppose user eliza created this word:
	: hello 
		"Hello, World" .
	;.

The difference between this hello and the previous version is that this one is ended using the word ;. instead of the usual ;

The word ;. in addition to completing the definition of a new word, also publishes it to the Smojo Cloud.

Once published, any Smojo programmer (with an internet connection) can immediately gain access to this word:

	\ prints Hello, World
	eliza/hello

Anyone can now use eliza/hello in their own words. No "installation" needed.

NOTE: By default, cloud words are "early bound" meaning the version of eliza/hello is frozen with your code. You may also "late bind" words, so that the latest versions on the cloud are automatically picked up.

The Smojo Cloud also includes some compute for endpoints -- words that communicate with the world over HTTP. We've also built a widget framework specially for handheld devices in Smojo (There is a complete self-study tutorial on Autocaffe's Labs). We use this framework to host our Chatbots.

For example, this code:

	
	\
	\ A simple Smojo webapp
	\
	
	terra/apps

	: ask-name >> lab-1
		{{ 
		     "What is" 
		     "Your"
		     "Name?"
		     text #name
		 }} splash
	;

	: say-name
		{{ "Hello"
		     @name
		 }} splash
	;

	: lab-1
		@name? -> say-name exit |. ask-name
	; \html	

	

creates a simple webapp.

You can try this app here: https://app.smojo.org/arnold/lab-1

This style of programming works remarkably well in practice. We've successfully built a cloud AI learning platform (Autocaffe) using it.

Smojo to C

The willow compiler converts Smojo programs to standalone C with no external dependencies. We may also include a compilation cloud so you can get the binaries directly, for Linux, Mac OSX and Linaro (Raspberry Pi), in addition to the raw C file.

We hope to use willow to simplify edge AI development for the Jetson Nano and other edge devices. Great for school or university projects.

Willow will be released as a cloud word for anyone to use.

Here's a program converted by willow which prints the Sierpinski gasket to screen:

Willow is currently in active development. A public alpha will be released in June 2020.

Conclusion

Congratulations on making it this far! :)

Take the logical next step and sign up for a free Autocaffe account. Then work through any of the introductions we've made to Smojo.

We hope you have fun.