Skip to content

Commit

Permalink
feat(content:docs): upd due to short :inport and :outport syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
emil14 committed Feb 22, 2024
1 parent f11d187 commit bccccf2
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 62 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.PHONY: prod
dev:
prod:
@hugo

.PHONY: dev
Expand Down
14 changes: 7 additions & 7 deletions content/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ Welcome to Nevalang, a programming language designed to transform the way you th
component Main(start any) (stop any) {
nodes { printer Printer<string> }
net {
in:start -> ('Hello, World!' -> printer:data)
printer:sig -> out:stop
:start -> ('Hello, World!' -> printer:data)
printer:sig -> :stop
}
}
```
Expand All @@ -27,8 +27,8 @@ component Main(start any) (stop any) {
subNode SecondComponent { depNode Printer<any> }
}
net {
in:start -> subNode:msg
subNode:msg -> out:stop
:start -> subNode:msg
subNode:msg -> :stop
}
}
Expand All @@ -37,8 +37,8 @@ interface IPrinter<T>(data T) (sig T)
component SecondComponent (msg any) (msg any) {
nodes { depNode IPrinter<any> }
net {
in:msg -> depNode:data
depNode:sig -> out:msg
:msg -> depNode:data
depNode:sig -> :msg
}
}
```
Expand All @@ -62,7 +62,7 @@ component Main(start any) (stop any) {
32 -> builder:age
'John' -> builder:name
builder:msg -> print:data
print:sig -> out:stop
print:sig -> :stop
}
}
```
Expand Down
4 changes: 2 additions & 2 deletions content/docs/about/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Add to this strong static typing, compilation into machine code, and open-source

## Why FBP? Why Not OOP or FP?

The reason why Nevalang might succeed is its flow-based paradigm. The stagnation in the problems described above, as we believe, is a consequence of the flow control paradigm established by the von Neumann architecture, where we have a state and a computer that changes this state by sequentially executing instructions. This way of thinking has served us well, but in the era of multi-core processors, we struggle to adapt it to modern realities. However, in the dataflow paradigm, and especially in its most powerful form - Flow-Based Programming (FBP), these problems do not exist.
The reason why Nevalang might succeed is its flow-based paradigm. The stagnation in the problems described above, as we believe, is a consequence of the control-flow paradigm established by the von Neumann architecture, where we have a state and a computer that changes this state by sequentially executing instructions. This way of thinking has served us well, but in the era of multi-core processors, we struggle to adapt it to modern realities. However, in the dataflow paradigm, and especially in its most powerful form - Flow-Based Programming (FBP), these problems do not exist.

## What Is Implicit Parallelism?

Expand All @@ -29,7 +29,7 @@ Nevalang features what we call _effortless concurrency_. This means that writing

Components exchange messages through buffered queues, and blocking only occurs when the queue is full. But even in this case, parts of the program that are not blocked continue to work.

The icing on the cake is the fact that Nevalang naturally supports stream computing right out of the box. It doesn't just support it - it's a native form for it. Where in conventional programming we process a batch of data and then pass it on, in Nevalang, we process and pass on data as it becomes ready. An entire page wouldn't be enough to describe how much this can speed up computations.
The icing on the cake is the fact that Nevalang naturally supports stream processing right out of the box. It doesn't just support it - it's a native form for it. Where in conventional programming we process a batch of data and then pass it on, in Nevalang, we process and pass on data as it becomes ready, piece by piece. An entire page wouldn't be enough to describe how much this can speed up computations.

## Why Visual Programming?

Expand Down
14 changes: 7 additions & 7 deletions content/docs/faq/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ component Main(start any) (stop any) {
print Print
}
net {
in:start -> b:sig
:start -> b:sig
b:err -> destructor:msg // ignore the `err` outport, only handle happy path
b:v -> print:v
print:v -> out:exit
print:v -> :exit
}
}
```
Expand Down Expand Up @@ -232,17 +232,17 @@ If you need to continue sub-stream you simply send `SubStreamItem<T>` from you w

It's either you continue sub-stream or you do not. Depending on what your're doing (maybe you're counting sub-stream items so you just sends `int` eachtime sub-stream ends).

## Why `out:stop` of the `Main` is't `int`?
## Why `:stop` of the `Main` is't `int`?

This is the question about why `out:stop` isn't interpreted as exit code.
This is the question about why `:stop` isn't interpreted as exit code.

The things is - you don't always have `int` as your exit condition. That's why it's `any`.

Ok, but why then we don't check if that `any` is actually `int` under the hood and then interpret it as an exit code?

Well, we can do that. But that would lead to situations where you accidentally have `int` like your exit condition but don't actually want it to be your exit code. Such cases are non obvious and will require you to somehow check that you send exit code you want.

This problem gets bigger when you have `any` or _union_ `... | int` outport that is directed to `out:stop` - you'll have to check whether value isn't an `int`. Otherwise you're at risk of terminating with wrong code.
This problem gets bigger when you have `any` or _union_ `... | int` outport that is directed to `:stop` - you'll have to check whether value isn't an `int`. Otherwise you're at risk of terminating with wrong code.

**Exit codes are important**. Shell scripts and CI/CD depends on that. Most of the time you want your exit code to be `zero`. Non-zero exit code is not happypath, it's more rare. Having corner case like a base design decision is not what we want.

Expand Down Expand Up @@ -305,9 +305,9 @@ So why you define struct/map literals with colons and commas? Well, the answer i
There was an idea to have sugar for connections where sender and receiver has same ports

```
in:sig -> scanner:sig
:sig -> scanner:sig
scanner:data -> logger:data
logger:sig -> out:sig
logger:sig -> :sig
```

To look like this
Expand Down
16 changes: 14 additions & 2 deletions content/docs/quick-start/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ To begin, download the Nevalang installation script using the following command:
curl -sSL https://raw.githubusercontent.com/nevalang/neva/main/scripts/install.sh | bash
```

If everything is ok you should be able to execute

```bash
neva version
```

And see output like this (version could differ):

```
0.4.0
```

## Creating Your First Project

Let's create a new project named `nevalang_test`. This project will include a `neva.yml` _manifest_ file and a `main.neva` source code file, which will contain a simple Nevalang program.
Expand All @@ -33,8 +45,8 @@ Next, open `main.neva` with your preferred text editor and add the following cod
component Main(start any) (stop any) {
nodes { printer Printer<string> }
net {
in:start -> ('Hello, World!' -> printer:data)
printer:sig -> out:stop
:start -> ('Hello, World!' -> printer:data)
printer:sig -> :stop
}
}
```
Expand Down
5 changes: 4 additions & 1 deletion content/docs/style-guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The Nevalang style guide outlined in this document sets the standards for organi

## Formatting

- **Comments**: Comments must be avoided in general. Strive to easy to understand API with your naming. However, when annavoidable, they must start with lowercase and end without a dot. Keep comments short and simple.
- **Tabs Over Spaces**: Tabs are preferred for their flexibility in displaying indentation and for being more data-efficient.
- **Line Length**: Keep lines under 80 characters to enhance readability, accommodate split-screen setups, and avoid horizontal scrolling, especially for those who prefer large text for eye care.
- **Entity Blocks**: Group similar entities (like types or components) within `{}` blocks for clarity, but use discretion for cases where separate contexts are needed.
Expand All @@ -26,7 +27,9 @@ The Nevalang style guide outlined in this document sets the standards for organi

## Naming Conventions

A general rule is that an entity's name should inherit context from its parent scope, eliminating the need for redundant context duplication
A general rule is that an entity's name should inherit context from its parent scope, eliminating the need for redundant context duplication.

Good naming arrives naturally from the development process rather than artificial creation. It eliminates the need for comments.

- **Packages**: Use `lower_snake_case` for package names up to 3 words.
- **Files**: Exactly the same as for files
Expand Down
8 changes: 3 additions & 5 deletions content/docs/tutorial/01/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Here is the smallest program in Nevalang that compiles. It absolutely does nothi

```neva
component Main(start any) (stop any) {
net { in:start -> out:stop }
net { :start -> :stop }
}
```

Expand All @@ -25,7 +25,7 @@ Next, we see a block of curly braces `{}` and inside another one with the keywor

```neva
{
net { in:start -> out:stop }
net { :start -> :stop }
}
```

Expand All @@ -36,13 +36,11 @@ In Nevalang, programming is _flow-based_, and instead of controlling the flow of
In this case, we see that data flows directly from the input port `start` to the output port `stop`.

```
in:start -> out:stop
:start -> :stop
```

In other words, our Main component does nothing. It just lets data pass through itself without having any impact on the external world. Essentially, it could be called a bypass, but in a Nevalang program, there must always be at least one `Main` component (we'll understand why later).

The curious reader may wonder, what about `in:` and `out:`? Why couldn't we just write `start -> stop`? The fact is that there can be any number of ports for both input and output (although typically there are no more than three on each side). Input and output ports can sometimes have the same names. To avoid confusion, we specify the direction - `in` is input, and `out` is output.

## What's Next?

What, think this program isn't useful enough? Then let's move on to the [next chapter](/docs/tutorial/02)!
26 changes: 14 additions & 12 deletions content/docs/tutorial/02/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ component Main(start any) (stop any) {
printer builtin.Printer<string>
}
net {
in:start -> reader:sig
:start -> reader:sig
reader:data -> printer:data
printer:sig -> out:stop
printer:sig -> :stop
}
}
```
Expand Down Expand Up @@ -117,9 +117,9 @@ Let's finally take another look at the network of our Main component:

```
net {
in:start -> reader:sig
:start -> reader:sig
reader:data -> printer:data
printer:sig -> out:stop
printer:sig -> :stop
}
```

Expand All @@ -135,20 +135,22 @@ The output port `data` of the `reader` node is directed into the input port `dat

## IO Nodes

Finally, the curious reader might wonder, aren't `in` and `out` also nodes? After all, they are not instances of some components?
Finally, the curious reader might wonder, what about port addresses without specified nodes like `:start` and `:stop`?

Correct, they are not. The fact is that there are indeed two types of nodes - _component instances_ and the so-called _IO nodes_, of which there are always two in the network of each component - the `in` node and the `out` node.
The fact is that there are indeed two types of nodes - _component instance nodes_ and the so-called _IO nodes_, of which there are always two in the network of each component - the `in` node and the `out` node.

Now, if you don't understand the following paragraph, that's absolutely fine. But for the most demanding readers, it is necessary to clarify that the `in` node contains only output ports, and the `out` node only input ports. This inversion might be confusing, but it is actually quite natural - a component reads data from its input ports as if they are the output ports of some node and correspondingly writes to its output ports as if they are someone else's input ports.
Now, the `in` node contains only output ports, and the `out` node only input ports. This inversion might be confusing, but it is actually quite natural - a component reads data from its input ports as if they are the output ports of some node and correspondingly writes to its output ports as if they are someone else's input ports.

Because you don’t have to think about it most of the time, Nevalang offers a shorter syntax for connections with IO nodes - `:<port>` instead of `<io_node>:<port>`. For example, `in:start` is the same as `:start`. One might ask, 'But what if an input port and an output port have the same name?' Well, you always have senders on the left and receivers on the right, so `:x -> :x` means `in:x -> out:x`.

## Reader, Printer and The Algorithm

Finally, let's dissect the algorithm our network executes. So, we have 3 connections:

```
in:start -> reader:sig
:start -> reader:sig
reader:data -> printer:data
printer:sig -> out:stop
printer:sig -> :stop
```

As we see, the `start` signal goes to the `reader` node into the `sig` port. The `sig` port typically signifies a _signal_ to start performing work. The `Reader` component is designed in such a way that upon receiving this signal, it will _block_, waiting for input from the keyboard. After the user enters text and presses Enter, the program will be unblocked, and the entered data will be sent to the `Printer` component, which, in turn, will print it out and emit a `sig` signal on its output. We use this signal to close our loop, forming a cycle. The program will terminate if "ctrl+c" is pressed, but until then, it will continuously operate, constantly waiting for input and then printing it, ad infinitum.
Expand All @@ -164,9 +166,9 @@ component Main(start any) (stop any) {
printer Printer<string>
}
net {
in:start -> reader:sig
:start -> reader:sig
reader:data -> printer:data
printer:sig -> out:stop
printer:sig -> :stop
}
}
```
Expand All @@ -175,4 +177,4 @@ It still works! In fact, the compiler implicitly injects the `std/builtin` impor

## What's Next?

Well then, the Nevalang programmer is almost ready! Perhaps it's time to tackle a real problem. In the next chapter, we'll write a [hello world](/docs/tutorial/03)!
Well then, the Nevalang programmer is almost ready! Perhaps it's time to tackle a real problem. In the next chapter, we'll write a [hello world](/docs/tutorial/03)!
Loading

0 comments on commit bccccf2

Please sign in to comment.