Skov is a visual programming environment based on Factor.
Download the version of Skov adapted for your platform:
There is no installation process. Just extract the Skov folder from the zip or dmg archive and run the program.
Warning: There is currently a problem with the Mac version. To be able to run Skov, you will first have to open a Terminal, go to the Skov folder and run:
xattr -rc Skov.app
You might also need to disable Gatekeeper.
You will see this window.
The thing on the right is used to navigate the Skov environment. Each dot is actually a plus button in disguise. Click the bottom one or press
You can now enter the name of your word. Type
The red cross indicates that there is a problem with this word, it cannot be executed. Of course there's nothing in it! One of the dots on the left hides a plus button that allows you to add a word to the definition of your
The two nodes just beg to be connected together.
The arrow next to the
Click the result button and you should see the number 3.
Why did we use
To enter Skov code, you don't actually have to first enter all the nodes and then connect them together. You can do it in one step. If you place your cursor on a connector and press
This is the first word you define that has inputs and outputs, which means you can use it to process data. The previous words you defined just displayed something on the screen. This one doesn't display anything, but you can use it in another word. Let's do it.
Define a new word called
Click the result button and you should see "((voks))" because the input text
Look back at
The next example is going to introduce an extremely important concept.
Let's say we have some text and we want to keep only the letters that are represented by an even number (every letter is actually represented by a number behind the scenes). We do it like this:
Notice that the connection between
You can imagine the unconnected input of
Now we want to remove every letter that comes after "m" in the alphabet. Because every letter is represented by a number, we can do (if we know that "m" is number 109):
We can now use this principle to process some text files.
We want to reverse the order of the lines of text in a file. The last line will become the first and the first will become the last. That's easy:
(Of course, use the path to a real text file on your computer.)
If your text editor is intelligent enough to reload files automatically, you will see that every time you click the result button, the file is reversed.
We can also easily remove all empty lines in a file
How do we remove all the lines of a file that contain "hello"?
This one is great! We've seen that
I really need to emphasize the power of this.
When you want to remove all empty lines in a file, if you know that there is already a word called
Now some math...
These are the hyperbolic sine and cosine functions.
Go to Wikipedia to see these functions written in traditional mathematical notation and compare them to the Skov code. Do you agree that this code is a more beautiful representation of these functions than mathematical notation?
And the inevitable factorial function...
This one is interesting for two reasons.
The first is the
The second reason is the
It's now time to talk about objects. An object is a container for several pieces of data. For example, an object can contain two numbers, or one number and a sequence, or three other objects. An object belongs to a certain class. You can create a new class of objects by clicking the second dot on the right or by pressing
By clicking the only dot on the left or pressing
We can now create point objects that we can use to represent coordinates on a screen. When you define a class, the following words are defined automatically for you:
The first is a constructor, it takes two numbers and gives you a point object. The second is a destructor, it takes a point object and gives you the value of every slot. Next we have two accessors for the
We want to compute the distance between two points. Define a new word called
You will see that there are four dots on the left that let you insert a constructor, a destructor, an accessor or a mutator. Or you can insert them by pressing
Look at this code carefully. Do you recognize the Pythagorean theorem that you learnt at school? Do you agree it looks better now?
To test our
Skov tells you that there are two words called
Select the second
Now you can test this code:
See how we use two constructors to create two point objects that we pass to
By now we have encountered the three types of nodes that you can create on the right-hand side of the window:
Vocabularies can be created by clicking the first dot on the left or by pressing
If you know some other programming languages, I would like to take the time to highlight some differences with Skov.
I have just explained that words, classes and vocabularies do three different things: describing computation, describing data and organizing code. In other languages the distinction is not so easy. In object-oriented languages like Smalltalk and Java, the class is a concept used to describe data and organize code. You have to define your "words" (called "methods") inside classes. Classes take the role of vocabularies. The Scheme language relies on the concept of lexical closure, which is used to describe computation, hold data and organize code. Words take the role of classes and vocabularies. I believe having three separate concepts to describe computation, describe data and organize code makes things easier.
Most programming languages have a lot of syntax that you have to learn. They have parentheses, curly brakets, square brakets, semicolons all over the place. There is a syntax to call a function, another one to use a method of an object, another one to access an element of a list, etc. Skov does have some syntax (there is a special syntax for constructors, accessors, etc.) but much less than traditional languages.
Traditional textual languages force you to read the code from left to right, which, depending on the language, either means from the last function executed to the first ("the result is the sum of the squares of the even numbers in the list") or from the first function executed to the last ("take a list, find the even numbers, square them, compute the sum, return the result"). Python even forces you to mix the two approaches, which is horrible. You should be able to read code both ways because both approaches are useful in different circumstances. In Skov it is as easy to read code from top to bottom (from inputs to outputs) as from bottom to top (from outputs to inputs). Even better, it is as easy to write code starting from the inputs as from the outputs and only a visual language can do that.
Now we reach something even more fundamental. Traditional textual languages are one-dimensional. A program is just a long chain of characters. It means that you can easily compute something and pass the result to one other computation (you can chain functions together) but if you want to pass the result to several other computations it's more difficult. You have to give a name to your result and then use this name in several places to refer to your result. Skov is two-dimensional and this is why a result can be passed to several words directly (look at hyperbolic sine, hyperbolic cosine and factorial above).
In languages that have a module system (a module being the same as a Skov vocabulary, a thing that groups related functions together), imports are always a problem. The most common functions don't need to be imported because they are in a "base" module that is always active. If you want to use other functions, you have to write an import statement at the top of the file. You either import a whole module and you can use every function in it, or maybe you have to call your functions by module.function(), or you can choose to import just one function from a module. If a module name is too long, you can choose an abbreviation and write md.function(). This get tiresome very quickly! Having a module system is great because functions (words) are neatly organized into separate drawers instead of being in one big bag. Skov lets you use every word without asking you to tell it from which vocabulary you want to take it, as long as there is no ambiguity. It is only when two words have the same name that Skov will ask you to choose the one you want.
In traditional languages, the code is just one long chain of characters and every time the compiler or interpreter reads it, it has to find that "cos" (for example) means the cosine function that is defined in the "math" module. The code just contains the three letters "cos". In Skov (and I'm speaking of the code that resides in the image file here, not the code exported as text), every word that you see on the screen inside a word definition contains a direct link to the word that it represents. The compiler doesn't have to find the word you want to use every time, the information is stored permanently inside your code.
Another very fundamental thing. In a textual language, the programmmer and the system (compiler or interpreter) work with the same file but they don't have the same needs. The compiler would like to have a lot of information about everything: the module of every function, the type of every input and output. If all this information was present in the text file, the programmer would find it extremely hard to read. The programmer needs concise, compact code, with short names, even if it means there is a lot of implicit stuff going on. Actually, the programmer would be interested in having access to the same extensive information as the compiler (the module for each function, the type of each input and output), but on demand, not displayed all the time. Textual languages have to find a compromise to be readable so a lot of the information about the program is implicit and has to be reconstructed by the programmer and the compiler. In a visual language, the program can contain all the necessary information so everything is explicit. Only part of that information is displayed at a time to keep things simple but the programmer can have access to all the information on demand.
I don't want to say that visual programming is always better than programming in text files (the code for Skov is written in text files after all), but I want to show that textual languages have a lot of limitations that they will never overcome because of these fundamental constraints:
When you go, or go back, to programming in textual languages, I want you to be aware of these limitations and why they are here: because of the text file paradigm.
Every now and then, someone comes up with a new programming language with a slightly different syntax so that a particular type of operation is easier to express. But there are always compromises so inevitably other types of operations will be harder to express and there is no way to solve the problem while staying inside the text file paradigm.
Where does the name come from?
Skov means forest in Danish because Skov contains a lot of trees.
What is the goal of the Skov project?
Imagine that you don't know any programming language and that you don't have any programming tools on your computer, but you want to write a program to do a relatively simple task. Then Skov will be the easiest tool to use. It's going to be the easiest to install, the easiest to learn, the easiest to understand and the easiest to get working. This is the goal of the project.
How is Skov implemented?
Skov is based on Factor, which is a concatenative programming language (or stack language). Factor is not just a programming language, it's also a dynamic environment where you can see and modify everything on the fly. (It's inspired by Smalltalk.) There is a virtual machine written in C++ that executes the Factor code that makes the environment. The compiler that converts Factor code to machine instructions is itself written in Factor and is part of the dynamic environment. All the user interface is programmed in Factor except the low-level OpenGL primitives. It's really a fantastic system!
Skov is entirely coded in Factor. Most of the code is for the user interface. The rest is quite simple.
How is my Skov code compiled?
Skov code (by that I mean the hierarchy of objects that describe the tree that you see on the screen) is sort of converted into Factor code but not how you think. Skov does not generate code as a string of characters. The initial hierarchy of objects is converted into another hierarchy of objects that the Factor compiler can understand. The compiler then converts that to different hierarchies of objects to perform its successive optimizations. It's objects all the way down and there's never any text involved. It's a true visual system and there's no cheating.
Why did you choose this strange language, Factor, or whatever, to implement Skov? Woudn't it be better to recode everything in Jav...
Stop it! Stop it immediately!
I promise Factor was the best language to implement Skov, by far. It's a standalone system with useful libraries, it has its own virtual machine, it has an efficient compiler, it's very well designed, and it's very modular.
Factor really is a great system but nobody uses it because nobody likes the language. I hope Skov will make this great system useful to a much wider audience.
But couldn't Skov be coded in Skov?
In theory, yes! Maybe in the future it will be, but it's not a priority.
How can I run Skov in my web browser?
Why does everything have to run in a web browser these days?
Can the user interface, the documentation and the language itself be translated into other languages than English?
I think making the user interface multilingual but keeping English words in the programming language makes no sense, so everything would have to be made multilingual at once, but that would be an absolute nightmare to implement. Making Skov multilingual would be absolutely fantastic but there would be so much work to do that I doubt it will ever happen. Using a lingua franca is so much easier.
How can I contribute?
The project is hosted on GitHub. There you can report bugs and contribute to the development.
How mature is this project?
The Skov project started on 7 August 2015 so it's not very mature. But Skov is based on Factor, which has been developed since 2003 and is a mature system.
How can I share my Skov code with other people?
If you press