I learned to program on scratch in the 6th grade when it was very new, circa 2008. In many ways, it is more real than other learning languages.
In retrospect, the smalltalk influence of scratch I think left such an impression on me that I continue to love dynamic, always live environments to this day. The broadcast system is surprisingly powerful and forward thinking. I do recall it being a bit difficult to build up your own abstractions, but such guardrails I think are useful for learning and I usedd Scratch before custom blocks were available.
anyone else just define a function log(msg) the prints to stderr or maybe stdout and use that instead for simple programs/daemons? I never really got the big value proposition of seven-leveled logging or the complexity of it. If I need to customize it I just change my log function.
Thanks you very much for the support, I can totally understand that position.
We have been making great progress in terms of features since then to "flesh out" the languages and libraries including threading support, an event loop, and some basic networking (socket) support built in to the runtime. Generally though, the PL design space is already incredibly fatigued an most new languages claiming something have already been made a few times over, just doing doing one thing slightly better, so it is true we cannot truly compete in that space.
Janet is a hobby lisp(?) taken too far and I have been adding lots of features that I find useful for day-to-day programming and experiments while still being something "embed-able" into another project. Janet is not a corporate project in anyway and donations are accepted mostly as a token of gratitude and expenses used to maintain the website and CI bills. My goal is really just to make it a good, clean, useful language for my own use and not as some kind of advertisement or product for anything, it is a project I started in my college dorm and have continued working on as a passion project since.
A list refers to a singly-linked list, while tuples are implemented as immutable arrays. The former is flexible in that multiple lists can hare structure, and prepending to a list is an O(1) operation that does not change the original list (consing). This property allows all sorts of interesting data structures which at their core are simply lists of atoms and other lists.
Janet on the other hand just uses tuples, which are easier to pack densely into memory so usually have better cache performance on reads (clever lisp implementations can sometimes can make lists fit densely in memory, but usually they take about twice as much memory as a tuple).
splicing is the like the spread operator in JavaScript or the splat operator in Ruby. This turns out to be very useful in a language without cons for manipulating tuples in macros, even though it is not as efficient as a cons.
Firstly, this is a rather silly argument in general. One could say that Embeddable Common Lisp and Guile address the same niche and all developers from one project should consolidate in the other.
I have not used Guile to any extent, nor was Janet really influenced by it, but the comparison has been brought to my attention several times in the past. Janet is not scheme nor common lisp, so there are of course many differences that I cannot address here. However, as an extension languages, there are several things that I believe Janet does better than Guile.
Guile is not an ideal extension language for C projects (this is distinct from an extension language for GNU projects). Firstly, they address garbage collection with the Boehm GC, which takes some control over your runtime and is not known for great performance (the runtime/non standard C is the bigger issue). This was of course a decision made by Guile devs to make it easier to write correct bindings to C libraries in Guile, but it is not without it's downsides. Secondly, the project is not easy to embed in foreign build systems. Janet is more like Lua - built in tracing GC that is not conservative nor platform specific, no external dependencies beyond libc, and can be added to a project as an amalgamation (a single C file and 2 header files). This has enabled people to get Janet running more easily on a variety of platforms like mobile phones and even recently someone has been doing some work on getting Janet running on the Nintendo Switch. I believe Janet is also significantly smaller than even the smallest build of guile. Basically, Guile is not simple, which is (IMO) antithetical to an ideal extension language.
At the same time, Janet should feel like a much less minimal language compared to Lua. While core Lua limits itself to pretty much only standard C, Janet goes a little further to provide some abstractions over different platforms (that can be turned off via compile time options).
This does change the language drastically - source code is represented as tuples usually, although all of the core data structures have literal forms. This means writing macros is still easy, although certain idioms like consing are usually replaced by splicing, which is like unquote-splicing in Common Lisp but more general.
Janet uses setjmp/longjmp for error handling because most alternatives in C don't compose well or are incredibly verbose/inefficient. The C API is not documented yet, but in general one could use setjmp at C++/Rust <-> C boundary points to prevent panics from jumping over C++/Rust stack frames. However, many functions in the C API will not panic (longjmp to the last save point). The overhead could be minimized by only calling setjmp for API calls that can panic.
Seems to be elf vs mach-o - clang on linux is more or less the same size, actually larger than gcc. Probably also some linking stuff on macosx vs. linux.
Yes, on most linux systems its closer to about 375 kB right now with the default build. For some reason it is much smaller on macOS, and can be smaller when built with -Os, and even smaller when built without the assembler, peg, or in-binary documentation. You are right, it used to smaller but grew as I added more features.
Pretty cool tool, the NLP focus is surprising but I'm not sure if it is a marketing ploy or fundamental to the technology. The nice syntax is also an improvement over things like LPeg, which seem to obscure the grammar by forcing it to be written in Lua. Seems like it could overlap in functionality with Rebol/RED parse, which I believe has been posted on here before, LPeg, or just PEGs and Packrat parsing in general.
The parse engine is implemented with a PEG, so it is probably a lot slower, but also supports pattern matching over whole words. Also, the database aspect of Nevod seems interesting and offers potentially a huge speed. But as far as I can tell, the syntax looks like a PEG with some implicit rules that separate words. As far as speed goes, I definitely believe that Nevod could be very fast but I haven't seen any numbers.
Shameless plug, I've implemented something similar with PEGs for Janet, a lisp I have been working on for a while. I make no claims to it's speed, but the peg interpreter is written in tight C so it shouldn't be too slow. The peg module in Janet works with a DSL that looks like a lispy EBNF and results in a recursive parser compiled to bytecode for the interpreter.
Urn seems to be greater in scope and code. Fennel is intentionally small and a single file that can be dragged into any project.
Fennel does not try to provide Lisp idioms or abstractions unless they have a direct mapping in Lua. For example, there are no linked lists (use tables), and no continuations (use coroutines). Operators are implemented as special forms rather than function literals so that they can be easily implemented efficiently.
Fennel also includes abstractions that might not make sense in a normal lisp but help make interfacing with Lua code easier. For example, symbols that have a dot in them, like "table.insert", have the correct interpretation and can be used as normal symbols. Method calls are supported such via the `(:)` form; `(: "hello" :find "llo")` compiles to `("hello"):find("llo")`.
Fennel takes this approach because Lua is almost already a Lisp, so I felt it was best to add the minimum abstraction necessary. Also, I prefer simple and transparent tools.
Urn may provide more comfortable and "Lispy" abstractions, however, because it takes more control of the environment.
It also seems to have pretty great error messages compared to Fennel, and a good website. There are definitely some features in Urn that aren't
(yet) in Fennel, like built in pattern matching, although Fennel does do destructuring.
That's true. I don't want to criticize Guile or Lisp implementations in general, which have a number of features that Lua can't easily emulate (a numeric tower, true continuations, probably a whole lot more I'm not aware of), but I think Guile and Lua have very similar uses as embedded scripting languages (small, and with fast incremental compilation). Chances are if you using guile you may have considered Lua.
As for use-cases for Fnl, I would say it's more applicable for places where one would use Lua or Guile, rather than something like SBCL or any really fast, compiled Lisp.
Lua makes a pretty good dynamic language target, though, because of the many great implementations and small language spec.
I like lisp and prefix notation in general, but I definitely still prefer reading large mathematical expressions in infix. Its really just a matter of preference.
The largest reason for use of S exprs is making Meta programming easier. While certain things like arithmetic are more difficult with S-exprs, Macros and DSLs are far easier than with C like syntax. Since Lua is actually only a few steps from something like Guile, it takes very little code to translate a scheme like language to Lua without adding too much runtime overhead. The difficult parts of lisp to implement, namely closures, come for free.
With LuaJIT as good as it is, I would not be surprised if something like this would outperform guile.
In retrospect, the smalltalk influence of scratch I think left such an impression on me that I continue to love dynamic, always live environments to this day. The broadcast system is surprisingly powerful and forward thinking. I do recall it being a bit difficult to build up your own abstractions, but such guardrails I think are useful for learning and I usedd Scratch before custom blocks were available.