12 ms·
The Janet Language
- hislaziness 4y agoa bunch on examples on the first page - https://janetdocs.com/ https://janetdocs.com/
- 2h 4y agothis is really cool. I love how small it is. with the Windows package for example, you actually only need "janet.exe", which is only 791 KB.
- gleenn 4y agoSyntax looks a whole lot like Clojure. I immediately appreciate the optional immutability built in too.
- exitb 4y agoMake a note though that the immutable counterparts are not persistent, as the Clojure ones are.
- BWStearns 4y agoSo this is kind of like a lightweight non-jvm clojure? I like it. Looks like it could be a nice swiss army knife for data munging.
- haspok 4y agoYou mean Python, not Clojure. A number of key underpinnings, such as (almost) exclusively immutable datastructures are missing from this language. It is more of a Python with a LISP syntax.
- SyrupThinker 4y agoI'm pretty sure GP meant Closure, considering the language has matching immutable data structures for mutable ones [^1] and even its own (limited) version of EDN called JDN. It’s definitely also inspired by it. [^1]: https://janet-lang.org/docs/data_structures/index.html https://janet-lang.org/docs/data_structures/index.html
- masklinn 4y ago> I'm pretty sure GP meant Closure Closure is not a language so hopefully not? > the language has matching immutable data structures for mutable ones [^1] Looking at the lingo being used, the extremely limited breadth of ABI, and the complexity they assert around "immutable" data structures, they're clearly imperative data structures you can't mutate rather than the persistent data structures you'd expect from a strong clj inspiration. This page looks a lot more like a description of python datatypes than clojure, the only bit that Python lacks is an official frozendict.
- SyrupThinker 4y ago> Closure is not a language so hopefully not? Very true, the typo is strong in this one. > rather than the persistent data structures you'd expect from a strong clj inspiration What do you mean by persistent here? I assume some kind of shared memory instead of copying? Or something with more practical implications like deep immutability? > looks a lot more like a description of Python datatypes I am surprised where this sentiment comes from. Because of the initial comment? Basically any language nowadays has maps, sequences and byte strings. If I had to draw a similarity to Python it would be something along the lines of first-class generators.
- masklinn 4y ago> What do you mean by persistent here? I mean the class of data structures called persistent: https://en.wikipedia.org/wiki/Persistent_data_structure https://en.wikipedia.org/wiki/Persistent_data_structure > I assume some kind of shared memory instead of copying? Sure. > I am surprised where this sentiment comes from. Because of the initial comment? Because "tuple" for an immutable sequence is rather specific to Python. And data structures related to clojure (or functional languages in general) would have some sort of logarithmic component because they'd be tree-based. Pretty much the only O(1) operation in functional data structures is prepending to a linked list.
- SyrupThinker 4y ago
- dgb23 4y agoIf anything it’s major inspirations seem to be Clojure and Lua. It has some of the affordances of the former in terms of semantics, but is stripped down and friendly like Lua. The use cases also seem to overlap with Lua, as a fast, embeddable scripting language that you can easily keep in your head (see docs). It seems to be simpler than Lua because it doesn’t complect arrays and dicts into tables, as arrays are a separate construct. And it affords you with immutable versions of those. To me it looks like a Clojure-like for Lua use cases.
- n42 4y agoThe Lua similarity is not exactly a coincidence, the author of Janet also previously created Fennel[0], a Lisp for Lua. [0]: https://fennel-lang.org/ https://fennel-lang.org/
- jacknews 4y agoOr python with clojure syntax? The author also wrote fennel, a lisp/clojure-ish wrapper for lua, so I think that's the influence.
- BWStearns 4y agoI meant Clojure. Janet's "more default looking" data structures are the immutable ones which is a pretty strong nudge. I don't see any explicit callout about data sharing for Janet but if that's really all that's missing I still feel good about citing Clojure first.
- masklinn 4y ago> I meant Clojure. Janet's "more default looking" data structures are the immutable ones which is a pretty strong nudge. Except they're not immutable in the clojure sense (of persistent data structures), they're just fozen / readonly, as can be seen from their complexity bounds (and the lack of transients). And a quick check didn't show any incompatibility between the two worlds either.
- tsujp 4y agoSome prior threads: - https://news.ycombinator.com/item?id=28850861 https://news.ycombinator.com/item?id=28850861 - https://news.ycombinator.com/item?id=28255116 https://news.ycombinator.com/item?id=28255116 - https://news.ycombinator.com/item?id=23164614 https://news.ycombinator.com/item?id=23164614
- dang 4y agoThanks! Macroexpanded: Show HN: Make 3D art in your browser using Lisp and math - https://news.ycombinator.com/item?id=32738654 https://news.ycombinator.com/item?id=32738654 - Sept 2022 (38 comments) Janet – a Lisp-like functional, imperative programming language - https://news.ycombinator.com/item?id=28850861 https://news.ycombinator.com/item?id=28850861 - Oct 2021 (135 comments) Janet Programming Language - https://news.ycombinator.com/item?id=28255116 https://news.ycombinator.com/item?id=28255116 - Aug 2021 (114 comments) Janet: a lightweight, expressive and modern Lisp - https://news.ycombinator.com/item?id=23164614 https://news.ycombinator.com/item?id=23164614 - May 2020 (269 comments) Janet – A dynamic language and bytecode VM - https://news.ycombinator.com/item?id=19179963 https://news.ycombinator.com/item?id=19179963 - Feb 2019 (50 comments) Janet, a Clojure inspired language for scripting, or embedding in other programs - https://news.ycombinator.com/item?id=19172510 https://news.ycombinator.com/item?id=19172510 - Feb 2019 (1 comment) Janet, a bytecode Lisp vm - https://news.ycombinator.com/item?id=18759277 https://news.ycombinator.com/item?id=18759277 - Dec 2018 (1 comment)
- cfiggers 4y agoJanet is really powerful. Here's a small TUI text editor I'm writing in it, if you want to see a non-trivial example: https://www.github.com/CFiggers/joule-editor https://www.github.com/CFiggers/joule-editor
- BWStearns 4y agoThought the link was broke but GH looks broken now? Edit: Back up now
- DennisP 4y agoOoh, nice. I've been messing around with a weird text editor that started with that same tutorial, but in Nim. Janet is intriguing, I'll be digging into your code. How was the debugging experience?
- cfiggers 4y ago> I'll be digging into your code. My apologies in advance, then! (Ha.) The "main" function is at the very bottom of src/joule.janet. So I'd recommend starting there. As for debugging, Janet embraces REPL-driven development, so the debugging experience is all about setting up, interactively querying, and step-wise updating your program's state, live in memory, using the REPL. It's quite a bit different from a lot of languages—not better, intrinsically, just different. But I like it a lot. Is your Nim editor public anywhere? I've heard a lot of good things about Nim and wouldn't mind exploring a real-world example.
- DennisP 4y agoThanks :) Mine's not public yet, so far it barely does anything. I'm using a piece table and some other stuff that ended up being tricky to get right (hence my debugging question!), then I ended up taking a break. I haven't done much REPL-based work, maybe that would have sped things up. Maybe I should start looking at that again.
- ianthehenry 4y agoOh hey! Nice to see this on the front page here. I love Janet -- I've been using it for about year and a half, and it's now my go-to scripting language when I need something more powerful than bash, or when I want to hack on goofy little side project (some examples in my profile). Parsing expression grammars (think, like, declarative parser combinators?) are a really great feature for ad-hoc text parsing -- and nicer than regular expressions, in my opinion, for anything longer than about ten characters. The language itself is also a great introductory language-with-lots-of-parentheses, so you can explore compile-time metaprogramming with familiar runtime semantics -- think JavaScript plus value types minus all the wats. The embeddability and easy distribution (compiles to a static binary on any platform) is a huge plus as well. Honestly I like Janet so much that I'm writing a book about it, because I think it's a shame that the language isn't more well-known. It's great! You should check it out right now!
- mike_hock 4y agoI went there, saw the Lisp syntax, and noped back out.
- spikyllama 4y agoline noise much? man, that example is not pretty
- nostrademons 4y agoIt's a Lisp. For anyone acquainted with other Lisp dialects, it's about as readable as it gets.
- epgui 4y agoIf you're not used to working with lisps, your reaction is basically just unfamiliarity, and not actual discernment. Lisps are inarguably and objectively syntactically simpler than non-s-expression languages.
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- klyrs 4y agoPro-tip: move every open-paren to the right of its first enclosed token.
- gus_massa 4y agoIt also help to move each closing paren to it's own line, so instead of ))) it looks like ) ) ) It's almost the same number of parens, just a different formatting.
- epgui 4y agoPlease don’t do this… There’s plugins for working effectively with lisps. You probably just need the rainbow parens or better contextual highlighting.
- noreact 4y ago[flagged]
- billfor 4y agoDammit Janet.
- jimbo9991 4y agoThis is really cool, surprised it has so few stars and I've never seen it talked about here. I like the LISPs but I've always thought not having a CPython type thing was a bit of a deal breaker for making it a go-to "primary" language that I would use everyday. I'm definitely going to try with Janet though.
- masklinn 4y ago> I've always thought not having a CPython type thing What cpython type thing? Do you mean a rich(er) set of built-in datatypes? Because lots of lisps have that, some (e.g. clojure) also have reader macros for pseudo-literals. Even Scheme has had a built-in hashmap since R6RS (2007), and R5RS implementations usually provided hashmaps even if they were not spec-defined. Common Lisp has had a hashmap more or less all along (at least since before ANSI standardisation)
- iLoveOncall 4y ago> surprised it has so few stars and I've never seen it talked about here Why? It's a niche language in a dated syntax, with use cases already covered by other languages. You will downvote because you don't like that, but it doesn't make it less true.
- xigoi 4y agoHow is the syntax dated? I'd argue that S-expressions are timeless.
- iLoveOncall 4y ago((Oh,) (I (don't (know.))) (Just (a (random (thought (I (got.))))
- xigoi 4y agoHow(is(it(different(from(C-style(function(calls)))))))?
- dvh 4y ago[flagged]
- deusum 4y agoThe parentheses would appear to antagonize the humours.
- rurban 4y agoNormal people prefer syntax-less, unambiguous lisp-languages over the mess we have now. Just look at Javascript, rust or C++ and tell me normal people prefer that. Only worse languages win, because people are masochochists, but throwing away this possible user base is always a win.
- dvh 4y agovar distance = sqrt(x * x + y * y) That is something very similar they may had in high school.
- tasuki 4y agoMath notation is familiar, yes. Are you also saying math notation is good? Is it an example to emulate? I always thought math notation was atrocious to the point of discouraging me from the subject. Who knows, had mathematics used saner (simpler, consistent, perhaps slightly more verbose) notation, I might've been better at it.
- andsoitis 4y ago> Are you also saying math notation is good? If mathematics notation were as terrible, horrible ad you say, wouldn’t mathematicians have changed it by now?
- gus_massa 4y agoMath notation is terrible! I write like 4 or 6 midterms for Algebra and Calculus for the first year in the university. We are using LaTeX (for most of them), but we need to write LaTeX assuming the copy machine is not very well maintained. For example, we can't write $e^{-\frac{x}{2}}$ because the minus and the bar of the fraction may not be clearly separated. Also x and 2 will be too small. A solution is to use \dfrac to make them bigger, but the 2D structure of the formula will make the e and 2 be too close and confusing. After some year of trying, one of my coworkers insisted in using $e^{-x/2}$ that is ugly but copy-machine-poof. We also need huge integrals for $\int_0^7\dfrac{1}{1+x^2}\ dx$. The standard one is too small. I tried to write a macro for that, but the 0 and the 7 must be in weird positions. Also, there are too many cases, because the limits may be missing. Finally, we are using https://ctan.org/tex-archive/macros/latex/contrib/bigints https://ctan.org/tex-archive/macros/latex/contrib/bigints with some tiny macro to rename it to \lint because I don't like the names the author used. The math notation is very good to write in dead tree paper with a pencil in 2D, but in 1D with a keyboard or automatic processing is horrible.
- WalterBright 4y agoI just can't let go of infix notation.
- MathMonkeyMan 4y agoWith macros, someone can write an infix sublanguage for you to use in those mathy bits of code. Probably better just to get used to prefix notation, though. Just pretend everything is a function call.
- WalterBright 4y ago> Just pretend everything is a function call D uses Universal Function Call Syntax, where: f(a) g(f(a)) can be written as: a.f a.f.g It's a very popular feature.
- MathMonkeyMan 4y agoScheme has a shorthand for (cons a b) that's just (a . b), and (cons a (cons b c)) as (a b . c) Racket, a scheme-based language, extended the syntax so that any symbol appearing between two periods and not at the end of a list gets moved to the head of the list, so (a . b . c) becomes (b a c), which some people use so that (a . + . b) becomes (+ a b). The D syntax you describe is what schemes call the "threading macro," or the thrush combinator in non-macro contexts.
- soegaard 4y agoI believe the general consensus is that the double dot notation might not have been the best idea. FWIW it's mostly used for inequalities like `(a . <= . b)` which some people find easier to read than `(<= a b)`. But `<=` allows more arguments as in `(<= a b c d)` and here the double dot notation can't be used.
- pmoriarty 4y agoI love Lisp (particularly Scheme), and heard that Janet was strongly inspired by Lisp and is "really Lisp underneath", but is really fast and strong at math, so I thought I'd give it a try, and after learning it I started wondering to myself, "why am I not simply using Lisp?" Though arguably lispy, Janet just wasn't lispy enough for me. It was missing the simple, elegant sexp syntax I dearly loved, and I started to wonder what huge win I was getting from using it instead of just using Lisp or Scheme? Having not found a good answer, I did just that. That was the last time I bothered trying to learn a "Lisp-like" language that wasn't actually a Lisp, and decided to just stick to Lisp/Scheme. They do everything I need, are good at math, and are plenty fast enough for me.
- progre 4y agoI think its a pretty nice language. Those extra bits of syntax that makes it "not a lisp" are mostly around defining "not list" kind if data structures. I find it practical.
- cosmojg 4y agoWhat data structure isn't just a list with extra steps?
- MathMonkeyMan 4y agoAlmost anything but a list
- adenozine 4y agoAny examples to add, or you just want to leave it at pithy comment?
- MathMonkeyMan 4y agoSure, my thinking is that a cons cell can build singly linked lists and node-based binary trees. Some data structures are based only on those, but most involve an array of some kind. In scheme, for example, it's the combination of cons (i.e. lists and trees) and vector (i.e. arrays) that allows for arbitrary data structures. It's very constraining to have only the lists. - array: not a singly-linked list. - hash table: often an array of singly-linked lists, so not a list. - red-black or AVL tree: can be built with cons cells. - doubly-linked list: not a singly-linked list - double-ended queue: array of double-ended queues, so not a list. Could also be implemented as a doubly-linked list.
- moffkalast 4y agoIs it a good place Janet or a bad place Janet though?
- epgui 4y agoThis is Lisp, it’s definitely the Good Place (TM).
- ElfinTrousers 4y agoI decline to use this language unless it's Disco Janet.
- deleted 4y ago[deleted]
- crabbone 4y agoOne thing that bothers me about languages that compose functions like this f(g(x)) is that when programming interactively f is typically an afterthought. So, you start out with g(x) and then need to go all the way back and add f. Similarly, when x turns out like it needs to be elaborated, and you either have to go all the way back, or edit the expression in place making it longer and inevitably facing problems with terminal length and terminal input being determined by when you press "Enter". I like Lisp languages, and would take Scheme over Python for my job in a heartbeat, if I was allowed to. But, I think, that if we want interactive Shell-like programming, we really need to address the issues above in the language. Shell pipes are a good start, but they are quite restricted in what they can do and require xargs "extension". Some languages also have the "where" form, where arguments to a function can be elaborated after the function call. If I was ever to design a language for interactive programming, I'd certainly try to have these two features in it.
- adrianmsmith 4y ago> So, you start out with g(x) and then need to go all the way back and add f. That's one thing I will say after coming from Perl/PHP to Java, is that despite its verbosity and the uselessness of having to write .stream(), I much prefer Java's stream.map(...).filter(...) syntax over the more functional-style filter(map(list, ..), ..) syntax. The Java syntax reads left-to-right, which is the order you want when you're thinking about code, and also as you say writing it. I think if I were creating a programming language I too would try to make stuff read left-to-right as much as possible.
- ocimbote 4y agoAligning reading order with flow of actions is so important! That's why I use and msybe tend to abuse the `->` and `->>` macros in Clojure and the pipe operator `|>` in Elixir. Hopefully soon in JS as well, if I've read correctly.
- mst 4y agoIt's notable that raku (previously known as perl6) lets you write things in either direction, if I remember correctly something like @source >>> map { ... } >>> grep { ... } >>> my @sink; though note I'm typing from memory on my second coffee so I may have got that slightly wrong. Plus of course there's many languages with a |> operator so you can do g(x) |> f I also (the example is specialised for I/O but the implementation technique could trivially be borrowed for something that wasn't) implemented something sort of in this direction for perl once: http://p3rl.org/IO::Pipeline http://p3rl.org/IO::Pipeline I'm not convinced that left-to-right is -always- the best option and prefer having the choice of both, but I wouldn't be at all surprised if a survey of developers found that if they could only pick one they'd pick left-to-right, and while I'd find it hard to choose for myself alone I'd probably pick left-to-right on the basis that it'd likely make it easier to onboard people to any given codebase.
- jgrodziski 4y agoThere is also the jank language [0] that plays in similar fields. > jank is a general-purpose programming language which embraces the interactive, value-oriented nature of Clojure as well as the desire for native compilation and minimal runtimes. jank is strongly compatible with Clojure. [0]: https://jank-lang.org/ https://jank-lang.org/
- gigatexal 4y agoThe lisp style syntax is jarring
- wheelerof4te 4y agoHonestly, to me it is unreadable. Defining function inside a function inside yet another function where you use a for loop kind of function. It requires a much different line of thinking to be applicable in the real world, which goes against historic human nature of following specific instructions, one instruction at a time.
- piranha 4y agoNot really, you're looking at this very superficially. It's just an unfamiliar syntax. If you're really interested, just try to get through that syntax once and you'll find that it's not that alien.
- nordsieck 4y ago> Honestly, to me it is unreadable. Defining function inside a function inside yet another function where you use a for loop kind of function. Perhaps you think the same thing about JS where that was (and maybe still is?) a common idiom. Except that people didn't give those functions names. And for sure, it's possible to do it in all sorts of languages: python, ruby, js, go, and of course lisp I get that the syntax is "weird", but honestly, the only two real difference is that the parens are "on the wrong side" for functions/expressions, and the indentation is truncated (the trailing side of the paren pyramid is accumulated and stuck to the end of the last functional line).
- wheelerof4te 4y agoDoing that stuff in Python would further slow down an already slow language to a crawl. Calling non-builtin functions in cPython is super expensive.
- tmtvl 4y agoIt's a shame the new Lisps tend to not rip off Common Lisp's type system, being able to declare my types and having SBCL admonish me when I'm doing something stupid is something I would hate to lose.
- BaculumMeumEst 4y agoIsn’t it more accurate to call that unspecified SBCL behavior than “common lisp’s type system”?
- lispm 4y agoThe syntax to declare types is specified. What to do with the declared types is then to be specified by a specific implementation. Typical possibilities: * ignore * use for optimizations * use for type assertions and type checking
- tmtvl 4y agoIt is. SBCL does a lot of really nice things and it would be nice if someone who were to design a modern Lisp would take inspiration from it. That said, Common Lisp is hyper advanced alien technology, so it is hard to improve upon.
- davbryn 4y agoI think the language is unreadable. For me, the purpose of a programming language is to let a human talk to a machine. Show me (for instance) control flow for the example function on the home page. It just isn't making things easier
- xigoi 4y agoHow does the example not show control flow?
- StreamBright 4y agoI guess: f x -- obscure and mathematical (f x) -- too many parentheses f(x) -- PERFECT
- fm2606 4y ago>> (f x) -- too many parentheses >> f(x) -- PERFECT They have the same number of parentheses. f(x) is probably something you have seen for the majority of your life as this is how math is taught.
- StreamBright 4y agoI was just saying that syntax arguments most of the time are silly. I like LISP and ML languages, so for me it doesn't really matter if I need to write LISPy code or ML code.
- ElfinTrousers 4y agoWell hold on, what's wrong with (f) x?
- hnlmorg 4y agoReadability can be a subjective property. For anyone who’s spent even a casual amount of time with S-Expressions, the example code is extremely readable. But if ALGOL-like code is your main source of experience, then Janet will look like executable line noise.
- 4y ago
- kensai 4y agoSounds a lot like the space of Lua. How do they compare?
- ianthehenry 4y agoThey're similar! The author of Janet previously wrote https://fennel-lang.org/ https://fennel-lang.org/, a compile-to-Lua language. Janet has more traditional scoping rules than Lua. Tables and arrays are separate types in Janet, and arrays are 0-indexed. Biggest runtime difference is probably that Janet has value types. I think the compile-time programming is the real differentiator, but it's hard to summarize what that means in a comment. Performance is pretty similar to the vanilla Lua interpreter in the benchmarks I've seen and run (Janet typically wins slightly), but there's no LuaJIT.
- iainctduncan 4y agoIf you like things like Janet, you might also like s7 Scheme. It is also a minimal Scheme built entirely in C and dead easy to embed. I used it to make Scheme for Max and Scheme for Pd, extensions to the Max and Pd computer music platform to allow scripting them in Scheme. (https://github.com/iainctduncan/scheme-for-max https://github.com/iainctduncan/scheme-for-max) Janet was one of the options I looked pretty closely at before choosing s7. The author (Bill Schottstaedt, Stanford CCRMA) is not too interested in making pretty web pages, ha, but the language is great! https://ccrma.stanford.edu/software/snd/snd/s7.html https://ccrma.stanford.edu/software/snd/snd/s7.html
- simon_acca 4y agoInteresting! Janet clearly stands on its own with many unique features, that said if you are looking for a "scripting Clojure", also consider Babashka which can tap into many very high quality libraries from the Clojure ecosystem. https://github.com/babashka/babashka https://github.com/babashka/babashka
- noting0002 4y ago[dead]
- ianthehenry 4y agoJanet doesn’t have regular expressions built in to the language. Instead, you write parsing expression grammars. https://janet-lang.org/docs/peg.html https://janet-lang.org/docs/peg.html Spork has a regex-like syntax for constructing PEGs, but the semantics are slightly different. And http is also part of spork, which you have to install separately. (jpm install spork)