Top
Best
New

Posted by yacin 8 hours ago

Why Janet? (2023)(ianthehenry.com)
345 points | 168 commentspage 2
wodenokoto 8 hours ago|
I've been drawn into the Janet posts that surface every once in a while here on HN, but found the otherwise highly praised "Janet for Mortals", not being for mortals at all.
veqq 2 hours ago||
I have some gentler introductory stuff like: https://janetdocs.org/tutorials
lelanthran 7 hours ago|||
> I've been drawn into the Janet posts that surface every once in a while here on HN, but found the otherwise highly praised "Janet for Mortals", not being for mortals at all.

I'm surprised: the language is very straightfoward, simple, very few rules to remember. It's a Lisp but with a very small surface area.

I mean, compared to other languages, Janet really is easier to lean, so I'm surprised that the book for it is difficult (did not read the book, but familiar-ish with the language. I don't have anything but praise for it, TBH).

petee 7 hours ago|||
Personally I get hung up on the macro syntax being near the beginning, but there is so much valuable stuff past that
shevy-java 7 hours ago||
> not being for mortals at all.

I had that with Haskell. Although, while Haskell is too hard for me, I actually like its syntax.

Janet seems to be Lisp 2.0, so the syntax is lispy.

0x0203 7 hours ago||
Seems some of the listed advantages for Janet would also apply for tcl (small/simple, easy to learn, embeddable, usable as a shell, great for domain specific languages). It would be interesting, to me at least, to see a fan of Janet compare the two.
embedding-shape 7 hours ago||
I've only used Tcl briefly, mostly for automation which it's great at. But it's a Algol-like imperative language, doesn't have any type of macros and makes everything based on strings (which makes sense for automation) instead of lists, with all the tradeoffs that comes with.

It seems easier to figure out what the similarities are, because I think they're pretty few, they seem to differ more than they are similar.

adrian_b 5 hours ago||
Tcl being based on strings creates the same problems like in bash scripts, i.e. it is too easy to misuse the quotation rules, leading to subtle bugs.

Using for scripting LISP-like languages is much more foolproof, especially for more complex scripts.

packetlost 3 hours ago||
Ok, but now I want to embed Janet in a TCL program
ux266478 4 hours ago||
Janet is faster, but lacks anything like tk. It's probably also quicker to learn, as you don't get into complex evaluation structure until you start messing around with quasiquotes, while tcl requires you to understand mixing 3 different layers of evaluation right off the bat. tcl's vm imo is easier to understand as well.

tcl if you want a UI, janet if you want an embedded scripting language.

1vuio0pswjnm7 4 hours ago||
The author does not mention that Janet comes with _built-in_ networking

Having tried many tiny interpreters over the years, that's relatively rare IME

skeledrew 8 hours ago||
This got me thinking of Hy. I wonder how syntactically close they are; there might be an exploitable Python -> Hy -> Janet path here.

[0] https://hylang.org/

cfiggers 3 hours ago||
I use both. They're similar for simple use, but above a certain level of complexity Hy has a lot of Python-isms that bleed through. It really doesn't ever let you forget that underneath all the parentheses you're really writing Python. Janet feels like its own stand-alone language in that respect, where Hy is more like a syntax swap.

I have the impression that Hy's user base is larger, though (not that either one is huge).

rcarmo 8 hours ago||
I used Hy for a long time, then tried Janet, and ultimately realized that I wanted more batteries included but didn't want Python... So I forked https://github.com/rcarmo/go-joker and am tinkering with it until it does all I want.
AHTERIX5000 6 hours ago||
Does embedding Janet still lean on global state?
OskarS 3 hours ago|
My first question too, and I checked out the linked book [1], and sure seems like it! There's global functions like `janet_init()` and `janet_loop()` all over the place.

A language shouldn't advertise itself as "embeddable" if it does this. It means you can't have multiple interpreters, you can't use it on multiple threads, etc. GNU Guile does this too, and it's a baffling decision! For my field (audio plugins like VSTs), it means it's absolutely a no-go, because hosts can load any number of instances of your plugins and potentially run them in parallel in the same address space, they can't rely on global state like this. Each interpreter has to be separate.

Lua does this right, as does Python (as of 3.12, when they made the GIL local to each interpreter) and I think most of the JavaScript engines. And it's not hard, instead of a global `janet_init()`, just have an opaque pointer bundle all the state, like `janet_init(interpreter)`. If you want a global interpreter, just stick it in a global variable.

[1]: https://janet.guide/embedding-janet/

petee 2 hours ago||
Janet global state is thread local;[1] janet_init() is called once per thread.

[1] official docs: https://janet-lang.org/capi/embedding.html

zabzonk 6 hours ago||
Thought this might be about JANET, the rationale for which I have never really understood. The wikipedia article on it is not very explanatory: https://en.wikipedia.org/wiki/JANET
defrost 8 hours ago||
Previously (April 2023) | 140 comments: https://news.ycombinator.com/item?id=35539255
lindig 8 hours ago||
> Instead of regular expressions, Janet’s text wrangling is based around parsing expression grammars. Parsing expression grammars are simpler, more powerful, and more predictable than regular expressions.

I would dispute that this is the case. In PEGs, alternatives are not commutative, unlike in regular expressions. This can lead to quite frustrating debugging. While a valid choice, the advantage over REs is overstated.

jsmith45 2 hours ago||
I'd argue they are not commutive in regexes either, at least as implemented in practice. Implemented regexes favor the leftmost alternative even when both sides of the alternative match. This matters in cases like: capturing groups, and backtracking implementations. There absolutely are cases where one ordering of alternatives could yield catastrophic backtracking for some input, while the other will avoid it completely.

I personally don't like this at all. This means that regex engines that try to generate optimized matching code for an expression can end up generating suboptimal code if you don't want alternative order to matter, since the engine needs to keep that invariant, except in the case when it can prove that the alternatives won't overlap, and a later one can be checked in constant time. If both are true, it is legal to reorder them to do the constant time check before the big complicated wildcard-filled alternative.

But personally, I have never written a regex where I actively cared about the alternative evaluation order. I've used some other people made where order is important but never written one myself.

I'd love to be able to tell the engine "feel free to swap the evaluation order of my alternatives while optimizing", but few if any such engines offer that as a feature.

Now I get that PEGs have commutivity problems are that are different from regexes', which make the issue worse, but that doesn't mean regexes do things right either.

xigoi 7 hours ago|||
The non-commutavity is a feature, not a bug. It allows you to have clearly defined parsing for grammars that would traditionally be considered ambiguous.
layer8 4 hours ago||
But that’s not how humans writing code generally think about ambiguous expressions. You can see that by how few precedence rules programmers tend to internalize, and often prefer extra parentheses to make sure that the parser interprets it the way they mean.
xigoi 3 hours ago||
I am not talking about operator precedence, that’s a separate thing. Consider the parsing of math expressions, where juxtaposition of terms denotes multiplication unless it can be interpreted as something else. So f(x+2) is function application, whereas 3(x+2) is multiplication. With a PEG, you just write a standard expression grammar with an additional choice at the end for the implicit multiplication. With a conventional parser, this is much more difficult – you have to explicitly list all the different ways that terms could be next to each other without meaning something else.
petee 7 hours ago|||
"small peg tracer"[1] is really helpful for breaking down a PEGs operation

[1] https://github.com/sogaiu/small-peg-tracer

zelphirkalt 7 hours ago|||
PEGs are just soooo much easier to read than regexes for anything more complex than a few words or single line matching. REs are a hammer that tempts people to see everything as a nail, but once one progresses beyond that phase one usually wants as few REs as possible.
layer8 4 hours ago||
That’s mostly an artifact of concise regex syntax I believe. When you write regular expressions in an ABNF-like form, they become much more intelligible.
bmn__ 7 hours ago||
Came here for this comment. Janet would score positively in my mind if the evolutionary dead-end PEG were replaced with a grammar parser that is known to work under all circumstances.
6LLvveMx2koXfwn 8 hours ago|
Maybe needs a (2023) in the title?
More comments...