It’s super slow and strange and very unpolished, but I introduce you to Novika. Time was, I wanted to mix Self and Forth together. And here it is, about 6 months later. There’s little docs anywhere, nor in my head, because the language is quite hard to introduce and/or explain (even to myself). So cheers!
Nice! Where does the name come from?
I tried running it but it always says the same thing:
$ bin/novika examples/snake.nk Sorry: definition for needsPackage: not found in the enclosing block(s). └ IN [ … @: tvec2 […] @: game game . play 'Bye!' | echo … ] OVER [ | ]+
Please don’t copy-paste immediately :) It should be
$ bin/novika core examples/snake.nk. Notice
core is the folder in the repo which contains the “standard library” of Novika.
needsPackage: is a word which shouts at you in bloody red when a package is not found that is required by the script/file/block/whatever you’re trying to run. It happens to be defined in one of the Novika files in
Now, forget about what I’ve said. It’s actually
$ bin/novika core console examples/snake.nk. So you won’t ask me why it’s shouting bloody red at you that you need a console package and that you should “consult the frontend on how to do that” haha
It’s from the conlang Lingwa de planeta, aka Lidepla, aka a weird conlang which tries to be Esperanto for all continents. The word means “smth new (e.g. product)” as per their dictionary.
Idk if the previous message counted as a reply, maybe this will.
Unfortunately errors are one of the worst things you’d encounter in Novika, as horrible as it is for UX… They get scary, and they scare even me. They tell you nothing in particular. Moreover, the traceback thing is sometimes wrong (“rogue entries” is the term I devised, as if it makes anyone feel any better), for reasons too complex to explain here. In the most recent update I’ve removed most of the colors and shoutcase, and decided it’s good enough. Instead of the previous motto “Embrace the design” Novika should probably have:
At the extremes, simplicity comes at a cost.
What needs to be understood is that Novika, like Smalltalk and Self, is not really suited for file-driven development. I don’t yet know what kind of development it’s suited for, but certainly not file-driven.
It may sound that I’m criticizing my own language more than I’m advertising it, but really, these are things that must be accounted for right after you see the word “Novika”. Also, I can’t advertise a language that I myself kinda don’t know. It evolved so naturally that I didn’t notice when — and how — it became so complex. This is not another Python or C or Java clone, this is something new. How new is not for me to decide, it may just be a mish-mash of things — but it also may not.
Anyway, sorry for ranting. Have luck running that snake and let me know somehow if it worked :)
Thanks, it works! It runs pretty fast for me :-)
I guess I was confused by the output of
bin/novika when you don’t give it anything. I saw this:
$ novika core console example.nk ---- ------- ---------- a directory a package a file
So I thought:
- Okay, it seems I can run
novika coreand give it a directory
- Or run
novika conosleand give it a package
- Or run
example.nkis a file
So I tried the last one.
To clarify: I thought
novika core was the “compiler”, while `novika console" was the interactive console. But it looks like “core” is the “core” directory in the project, and “console” is a package. Maybe I was confused because I didn’t read the readme.
What I find strange is that you have to list the required packages on the command line, instead of having that information in the source code. In my mind, “snake.nk” would somehow require “core” and “console”, so I can run
novika examples/snake.nk. But I’m saying all of this without knowing much about the project’s philosophy, so feel free to ignore me.
I can’t ignore experiences of people trying out my language! I as the author must expect people to not read the readme and/or the help message and/or understand its philosophy (which isn’t even documented yet), and design with that expectation in mind.
This kind of feedback is very useful, although it’s too early to incorporate it into anything. Thanks for trying Novika out despite the initial “gruntiness” of the language. I know y’all have many things to do, especially you core team guys. 2 years of Crystal and very little problems for me, to the point where I can experiment like that.
You can implement
require or something like that in Novika itself. That’s how the REPL thingy works, it’s just smaller and dumber. The command-line interface exists as a faster way to run multiple files in proper order. Instead of listing all files in
core/ by hand, you say
core and Novika picks it up.
But the whole CLI thing is a stub I implemented a loong time ago, that’s why it’s so not-user-friendly.
And “packages” exist only so (a) language users have a way to yell at you if the interpreter was compiled without a feature (vocabulary) needed by the program you’re trying to run, and (b) to have a cleaner toplevel “namespace” initially. The latter is why you need to list them by hand. A hello world doesn’t need the console words in its “namespace”.
Novika is more suited for a GUI environment where you can zoom and drag and pan and create REPLs on the fly and, with a single keypress, transform them into blocks which you can then assemble into even larger blocks.
The uniformity of Novika wins in this case, because by creating a simple “block viewer/editor” for Novika you create a program that is able to (a) edit Novika code, (b) edit Novika data, (c) inspect Novika programs while they are running (when I implement a pause mechanism which is just a few LoC), (d) edit Novika programs while they are running, and (e) explore the system, meaning read the docs and look at the guts of the language.
The only disabled-by-default package is
console. In a graphical system, there would be no package console. A window would pop up when you
console:on, bringing the rest of the console words with it (or they may be defined already, this is undecided still). The world directory in the repo has a subset implementation of this, but it works with Novika 0.0.1 only. It’s a “file viewer”, not a “block viewer”, but still.
The problem of missing filenames and line numbers also disappears because you can just auto-pan and auto-zoom to the erroneous block and highlight the wrong part in red.
Moreover, one of the nicest things about blocks is that they can be diffed and patched easily, it’s almost as easy as diffing and patching arrays. And since these very blocks are running (or being run, by the engine), you can patch them inplace and have proper “live reloading”.
With some effort you can completely isolate a block and all its sub-blocks from the outside world and safely run them in parallel (as far as my understanding goes).
Also, if you or anyone else is really interested, check out any file in
tests/. With a lot of effort (until there are some words to ease that) you can make almost naturally-reading DSLs, with the help of some computation if needed.
Different languages have different things out of these, but none I’ve seen has all of them at once. Again, I am not the one to say whether it’s good or bad to have all of them. I’m happy it didn’t explode yet!
So yeah, another very long reply. Would be better if I documented so much :)