6 ms·
Janet: Lightweight, Expressive, Modern Lisp
- bjoli 1y agoIs there anything that is janet-unique? I just did a cursory glance, and most of it seems like a scheme with slightly different syntax and a more "modern" standard library. Why should I switch from my scheme of choice (guile) to Janet?
- veqq 1y agoIt's not a Scheme at all! It doesn't have cons cells after all. It's a Clojure-like (maps everywhere, collection api, immutable data structures) with 1mb executable and [servers](http://janetdocs.org/ http://janetdocs.org/) running under 10mb of ram. Fibers are very interesting, even used for error handling. I've not wrapped my head around PEGs yet.
- ggm 1y agoIf a language lacks cons can it truly be held to be a lisp or has heresy taken over?
- exe34 1y agoIt's got Lots of Indented Silly Parentheses.
- tkrn 1y agoAlthough I'm a recovering sexp addict I must confess that I fail to see what makes the cons cell so important to those purer in their faith? To me the homoiconity of Lisp is mainly about code-as-data, the exact nature of the data doesn't matter to me that much as long as it's a first class citizen and enclosed in nicely balanced parenthesis (though sadly here Janet seems to have fallen to the temptations of the curly braces, and thus, is indeed heresy).
- gorjusborg 1y agoI am a heretic, but I agree that it seems the power of code as data can exist outside a linked list. I will not give up my curly braces or square brackets.
- throwaway328 1y agoI chuckled at "recovering sexp addict". What possible risk is there in over-indulging in sexp?! I simply don't see it. Speaking of unconventional lisps, I enjoyed this recently: https://github.com/vygr/ChrysaLisp/blob/master/docs/lisp/lisp.md https://github.com/vygr/ChrysaLisp/blob/master/docs/lisp/lis... from Chris Hinsley, author of the (very) cool Chrysalisp operating system. Same author who wrote this in 1995: http://www.uruk.org/emu/Taos.html http://www.uruk.org/emu/Taos.html
- worthless-trash 1y agoThank you for janetdocs.org , I hated having the missing functions from janetdocs.com
- veqq 1y agoDo you have any suggestions or things to improve on? I'd like to know how others use it!
- worthless-trash 1y agoI have an emacs function that opens up the page to its examples use on the web, which can be useful directly from emacs itself. I'd also like to be able to open up each example up on to the playground with the docs above it. (Currently you can just open the example in the playground) no docs right above it. I did see a json file containing all site data at one point, I did think about using this as a data source for an llm to 'janet' correctly (because at the moment, they do not). This could be displayed/noted more prominently. None of these are 'must have', just nice to have.
- bjoli 1y agoThat makes sense. I have always thought about what I would do if I could make a "modern scheme". A lot would be taken from clojure but definitely not everything. Cons cells would stay, but the star of the show would be immutable vectors based on rrb trees or maybe finger trees (efficient concatenation, insertion in the middle etc), HAMTs , concurrentML (like guile-fibers) and a nice looping facility (like my own goof-loop[1]) and restricted mutation. Syntax-case and syntax-parse from racket. An extensible pattern matcher (like the one found in racket). I would also make strings immutable, maybe like Guile's cow-strings, maybe blobs-with-cursors. Definitely just copy Guile's delimited continuations. I think I would just ignore most of r7rs, since I don't think it improves things for the progrmmer.
- bjoli 1y ago[1] https://rikspucko.koketteriet.se/bjoli/goof-loop https://rikspucko.koketteriet.se/bjoli/goof-loop
- shawn_w 1y agoRacket has almost all of that.
- bjoli 1y agoI am no fan of racket's for loops. It is frustrating, because it fells like an almost-goosd looping facility. I do use racket, but for scripts I prefer guile. Guile-fibers is a lot neater than the racket parallelism situation, for example. And I can usually find the code responsible for what IAM trying to achieve in the implementation. I never became friends with racket. I remember trying to fix a bug, but I never found what I was looking for. Getting superficially familiar with the guile codebase takes about an hour. Then again, I am a classical musician and not a programmer.
- shawn_w 1y agoRacket's for loops declare in their name what they're intended to return (if anything). Personally that's way more readable and preferable to, say, Common Lisp loop or iterate where you have to hunt through the body for clues. Plus it's easy to create new ones when desired. I don't see fibers in the guile manual, just heavy weight threads. Is that a third party library? (The lack of a package manager to easily install such things is an issue with most Schemes; only chicken and chibi have anything like Racket's)
- girvo 1y agoPEGs (even outside Janet) are amazing and what I reach for all the time :) definitely one of those tools that’s worth learning!
- natrys 1y agoYep peg.el[1] is now built-into Emacs since 30.1 (which is how I came to know of it, but actually the library seems much older) and it makes certain things much simpler and faster to do than before (once you figure out its quirks). [1] https://github.com/emacs-mirror/emacs/blob/master/lisp/progmodes/peg.el https://github.com/emacs-mirror/emacs/blob/master/lisp/progm...
- bmn__ 1y ago> PEGs (even outside Janet) are amazing […] worth learning! Actually, the opposite is the case. https://news.ycombinator.com/item?id=32316375 https://news.ycombinator.com/item?id=32316375 HN readers, don't fall into this trap and waste your time.
- girvo 1y agoAh yes, I, the non-python programmer, find PEGs useful and good because of checks notes Guido, somehow? What a ridiculous comment.
- worthless-trash 1y agoI don't know enough about guile, but janet was pretty easy to develop for . Its binaries are quite small, could wrap and embed raylib and a few small c libraries with no hassle. This makes distribution much easier. For my simple 2d game jaylib (raylib) code. ls -laoh build/app -rwxr-xr-x 1 worthless 2.8M 27 Jul 17:28 build/app otool -L ./build/app ./build/app: /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1356.0.0) /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 24.0.0) /System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo (compatibility version 1.2.0, current version 706.41.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0) /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 2674.3.0) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 4034.0.0) /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics (compatibility version 64.0.0, current version 1951.0.4) /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 1226.0.0) /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 4034.0.0) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0) I believe those are pretty standard to have on most OSX machines, the situation is similar for my Linux system. The LLM's really can't deal with janet though, they seem to think its clojure and screw up a lot of things.
- johnisgood 1y agoFeed your LLMs the documentation and example code (perhaps the whole stdlib if it fits). Tell your LLM that it is not Clojure nor Scheme, it is a different language. I have worked with more niche languages than Janet with Claude before this way, successfully.
- asQuirreL 1y agoI would tend to use Janet for scripts, especially ones that need to talk to the outside world because of its fast startup and batteries included standard library (particularly for messing with JSON, making HTTPS requests, parsing with PEGs, storing data in maps), while I would use guile for larger projects where things like modularity, performance, or metaprogramming were more important to me. That being said, these days I use Clojure for both (I use babashka to run scripts: https://babashka.org/ https://babashka.org/)
- 3036e4 1y agoI did most of the 2023 Advent of Code using Janet and it was a great experience. I forced myself to use PEGs as much as possible, even when it was overkill, and I really began to like those for the readability and ease compared to other parsers/regexps that I have used. I like that it is a small language without dependencies. Have it installed everywhere, including in termux on my phone. Good for scripting. Used to daydream about a native Clojure and Janet is close enough to that. Does not have everything, but the cost in size and dependencies is so much lower. It is simpler and easier and runs well even on a RPi Zero.
- terminalbraid 1y agoOne big difference is you can compile Janet programs down to executables without any additional dependencies or runtimes. It makes distribution extremely nice. The ffi is also much easier.
- atemerev 1y agoIf you are happy with Guile, I guess Janet is not worth switching (it is faster, though). It is absolutely and explicitly not Scheme, though. More like natively compiled and script-optimized Clojure.
- xigoi 1y agoOne thing I really like about Janet, compared to Scheme, is that it’s one language instead of a family of similar but incompatible languages.
- dmpk2k 1y agoDoes it have a native compiler and/or types? Basically, can it get in the ballpark of SBCL's performance? It'd be nice to have something cleaner than Common Lisp, and a much smaller image size. If it has decent performance too, I'm sold.
- atemerev 1y agoThis is not a replacement for Common Lisp. It is in the same niche as Guile (but quite faster).
- terminalbraid 1y agoYeah, I see Janet as "what Guile intended itself to be", though it is quite a bit smaller (in some ways that's a postive). I find the choices it made to be more pragmatic and it's far more accessible in non-linux environments since Guile tied itself closely to guix.
- anthk 1y agoCurrent Guile it's much faster.
- terminalbraid 1y agoJanet does compile to standalone executables with jpm
- xigoi 1y agoJust keep in mind that these executables are the Janet bytecode interpreter bundled with your bytecode, not “real” native executables.
- terminalbraid 1y agoNo, they are actually real executables without the need of an external runtime. You can get images also if you like. See quickbin in the jpm man page. > Create a standalone, statically linked executable from a Janet source file that contains a main function. and discussion here https://janet.guide/ https://janet.guide/ > My favorite feature of Janet, though, is something that sounds really dumb when I say it out loud: you can actually distribute Janet programs to other people. You can compile Janet programs into statically-linked native binaries and give them to people who have never even heard of Janet before. And they can run them without having to install any gems or set up any virtual environments or download any runtimes or anything else like that. They're not super tiny, though. A hello world I just did is about 727K.
- NeutralForest 1y agoJanet is awesome but pretty please, work on the tooling. There's very little in the way of working and debugging interactively with the REPL from any IDE that I know of and last time I tried (on Emacs) there was barely a dedicated mode to work with it.
- worthless-trash 1y agoI use janet ts mode in emacs and Ajsc netrepl integration, for at least a while now. You should try again.
- deleted 1y ago[deleted]
- NeutralForest 1y agoI've been trying to use ajrepl but as mentioned in the README, there's a lot of cruft that gets output. How do you setup ajsc?
- worthless-trash 1y agoIn Emacs (add-hook 'janet-ts-mode-hook #'ajsc-interaction-mode) (add-hook 'janet-ts-mode-hook (lambda () (local-set-key "\C-c\C-x" 'ajsc))) (add-hook 'janet-ts-mode-hook (lambda () (local-set-key (kbd "C-x C-e") #'ajsc-send-expression-at-point))) In the janet itself: (def repl-server (netrepl/server "127.0.0.1" "9365" (fiber/getenv (fiber/current)))) If you have tight main loop, make sure you have something like: (ev/sleep 0) To allow the netrepl server to take time. Start janet (usually i do it via jpm) $ jpm -l janet -d main.janet Then m-x ajsc and localhost:9365 This should be default. If you dont start it in debug mode, you can't redefine functions as they are running. I have an example using it for live web stuff here: https://github.com/wmealing/janet-joy-live https://github.com/wmealing/janet-joy-live
- terminalbraid 1y agoJanet is also supported by conjure in neovim https://github.com/Olical/conjure https://github.com/Olical/conjure The LSP for it works reasonably well.
- mesaoptimizer 1y agoAlso see https://janet.guide/ https://janet.guide/ for a good introductory book to Janet.
- qart 1y agoThis is the first time I'm seeing the book. The author is solid! He has just the right sense of humour for a programming book.
- Lyngbakr 1y agoHe works at Jane Street and was recently on their podcast§. An interesting chap, for sure! §https://signalsandthreads.com/building-tools-for-traders/ https://signalsandthreads.com/building-tools-for-traders/
- raydenvm 1y agoAre there any known commercial use cases?
- revskill 1y agoI do not see how it handles async await
- terminalbraid 1y agoYou should take a look at fibers https://janet-lang.org/1.9.1/docs/fibers/index.html https://janet-lang.org/1.9.1/docs/fibers/index.html
- nemoniac 1y agoThe first code example on that page claims to solve "the 3SUM problem". According to [1], "the 3SUM problem asks if a given set of n real numbers contains three elements that sum to zero." It's not clear to me what problem the Janet code solves but it's clearly not that 3SUM problem. On the example input of @[2 4 1 3 8 7 -3 -1 12 -5 -8] it outputs @[@[6 1 7] @[2 5 10] @[1 2 9] @[4 6 9] @[3 0 9] @[6 2 0]] For what it's worth, here's some Common Lisp code that does solve the 3SUM problem in O(n^2). (defun 3sum (a) (let ((h (make-hash-table)) (len (length a))) (dotimes (i len) (setf (gethash (aref a i) h) t)) (dotimes (i len) (dotimes (j i) (when (gethash (- (+ (aref a i) (aref a j))) h) (return-from 3sum t)))))) (3sum #(2 4 1 3 8 7 -3 -1 12 -5 -8)) ;; => t [1] https://en.wikipedia.org/wiki/3SUM https://en.wikipedia.org/wiki/3SUM
- bmacho 1y agoIt outputs the indices corresponding to the solution. E.g. @[6 1 7] == A[6], A[1], A[7] == -3, 4, -1 @[2 5 10] == == 1, 7, -8
- lispitillo 1y agoIf you want a one line code, in J, for the 42 solutions: _ 11 11 #:,I. 0=,a+/,+/~ a=: 2 4 1 3 8 7 _3 _1 12 _5 _8 Or the 8 solutions in a 2x12 matrix: 2 12 $, ~. (/:~)"1 ({&a) _ 11 11 #:,I. 0=,a+/,+/~ a=: 2 4 1 3 8 7 _3 _1 12 _5 _8 _3 1 2 _5 2 3 _1 _1 2 _8 4 4 _5 1 4 _3 _1 4 _8 1 7 _5 _3 8
- WillAdams 1y agoIt is unfortunate that there doesn't seem to be a GUI library --- if there was one _and_ if one could easily compile to a stand-alone program for distribution, this would be very interesting to me. For bonus points, compiling to a stand-alone JavaScript wrapped in HTML would be awesome if it could be hosted on a Github page.
- terminalbraid 1y agoGiven your criterion for what a "fortunate" language would be, what language includes a GUI library, compiles to a stand-alone program for distribution, as well as "Javascript wrapped in HTML"?
- WillAdams 1y agoIt doesn't exist as an opensource option anymore (since Livecode did their rugpull) AFAICT, it's something I've been looking for since then. Similarly, they were supposed to offer "compile to HTML5", but it never really worked for me.
- terminalbraid 1y agoJust so I'm clear, you then feel compelled to openly and publicly label every literally programming language as "unfortunate" because it doesn't live up to what LiveCode aspired to be? An opinion that flatly and individually labels every extant thing the same has no signal to it. I'm not sure what to make of your original post other than you're expressing displeasure at the universe for not handing you what you wanted and that you believe that expression should be injected into arbitrary discussion.
- WillAdams 1y agoI will agree that the word choice was poor. Should have phrased it as something along the lines of: >This would be very interesting to me if it had support for a GUI library, and if it were then possible to compile to a stand-alone application which could be easily distributed.
- azhenley 1y agoPrevious discussions: https://news.ycombinator.com/item?id=23164614 https://news.ycombinator.com/item?id=23164614 https://news.ycombinator.com/item?id=34843306 https://news.ycombinator.com/item?id=34843306 https://news.ycombinator.com/item?id=28255116 https://news.ycombinator.com/item?id=28255116 https://news.ycombinator.com/item?id=28850861 https://news.ycombinator.com/item?id=28850861
- zelphirkalt 1y agoWhen I see languages like this, I always wonder, how far the ecosystem is. I have used GNU Guile a lot and there are quite a few libraries for it, so that one can do almost anything. Web things are coming, but maybe not as fully there yet, as one might like. Racket also has lots of libraries. And even a standard library web framework. So lets say I want to start my next web project in Janet. I already know Scheme and can probably quite easily just start writing another lisp, assuming it has TCO and I can do things mostly like I would in Scheme, except maybe for having to use funcall (which is annoying, but OK). Does Janet have libraries, that enable web projects? Like a web server and SXML or something like that? Or does it have things like a JSON parser? All these little things one would like to have, to not have to develop the basics first, before getting to the actual project. And what about data structures? Are there functional data structures available? In GNU Guile I have at least the unmaintained guile-pfds. Hopefully, I will one day understand enough about functional data structures to build more or to maybe even maintain that library. But learning resources are scarce. It is already difficult to find a functional version of an AVL tree! Lots and lots of places merely teach non-persistent, non-functional versions of these data structures, and it is not trivial to translate them, might impact performance in ways that are not necessary, if one had great knowledge about how to make these data structures. And also reproducibility! With GNU Guile I have what I need on Guix, which is great! With other languages, I might need to rely on older package managing approaches, that do not have reproducibility/determinism as the a high goal on their agenda, or might even lack the ability to create lock files/files with checksums. I don't want to go back to non-reproducible. I am also eyeing statically typed variants like Carp. Same questions arise. Some seem really great and I would probably enjoy using them a lot. Would be a pity to then discover, that the ecosystem is just not there, and one has to create all the basic tools one needs oneself. Sometimes that can be fun, but it can also be exhausting and one never gets around to ones actual project.
- veqq 1y agoJanet has ~10 web frameworks (half SSG, half dynamic) and many web servers. Joy [0] is the most fully featured stack approach, which Janetdocs [1] runs on. But everything you mention is in the std lib. Here's a certbot in 10 lines only using the extended std lib (called spork): https://codeberg.org/veqq/janetdocs/src/branch/master/ssl-fetcher.janet https://codeberg.org/veqq/janetdocs/src/branch/master/ssl-fe... `json/decode` automatically maps json to native data structures. There's a package manager included, which builds all code I've found so far, reproducibly. As for DS, only arrays, there are maps, arrays and strings, all mutable or immutable. I don't think there's any intention to ever implement functional data structures, but they could "easily" be a library. - [0] https://github.com/joy-framework/joy https://github.com/joy-framework/joy - [1] http://janetdocs.org/ http://janetdocs.org/
- uvas_pasas_per 1y agoLisp is very cool. But one thing I do not like is that the syntax style `(fun a b c)` loses out to the less-symmetric "OO" style `a.fun(b, c)` when it comes to IDE auto-completion. And for me the IDE help is important to provide a smooth developer experience and minimize wasted brain energy. I'd like to find a way to make the editing and auto-completion work better. I think the way IDEs (and maybe our brains) work is: "here is a thing X, now what can I do to/with it?". That translates to typing in your editor: "X.[cursor here]", and then the IDE lets you see and search the things you can "do" with X. But if, in Lisp, you write "([cursor here]", you are immediately confronted with: "what is the signature of that function again?", but the IDE has nothing to go on. Maybe there is different style of editing, where we could type the arguments, and then trigger the auto-complete.
- thegeekpirate 1y agoOdin's language server calls it "fake methods". https://odin-lang.org https://odin-lang.org https://github.com/DanielGavin/ols https://github.com/DanielGavin/ols
- kqr 1y agoHaskell sort of has this. You type (_ a b c) and the compiler tells you which methods would make sense there based on all three variables (so in a sense it is even more useful.)
- uvas_pasas_per 1y agoDo you mean you run a build and it tells you in the error message? Or is there an IDE/editor where you could hit a key-combo with the cursor on that line, or near the `_`, and it would show a popup of possibilities for auto-completion?
- kqr 1y agoYes. Both are alternatives.
- bcrosby95 1y ago
- rich_sasha 1y agoIs there some kind of decision tree for "which lisp should i use?". CL, Scheme, Racket, Clojure, Janet... Elisp at least is clear :)
- fredrikholm 1y agoCL for performance and 'Lispiness'. Scheme if you really enjoy recursion. Clojure if you need the JVM and/or employment (this is me). Racket if you drink the DSL kool aid. Fennel (same author as Janet) for Lispy Lua. Janet for Lispy C.
- spauldo 1y agoCL is like the C++ of the Lisp world. It's standardized, multiparadigm, has a ton of functionality, fast, and built with large codebases in mind. It's also got a lot of cruft and because the standard is old it lacks certain things people expect, like networking and threads. Implementations usually provide these and compatibility libraries do a decent job of smoothing over implementation differences. Choose CL if you have a team, a large project, and you need speed. Scheme was written for educational purposes. It's very minimal, and implementations aren't very compatible for anything outside the spec and the SRFIs (specs for optional functionality). I'd you choose a major implementation like Guile or Chicken however, there are tons of libraries available and it's very usable for small and medium-sized projects. It isn't known for its speed. Choose Scheme if you think like a computer scientist. I've never used the others enough to comment, although I did enjoy playing around with Clojure since it's a functional language. I'd do more with it if it wasn't tied to Java and JavaScript. I keep telling myself to learn some Racket, but I never have the time. Personally, I do most of my Lisp work in elisp, since my regular job isn't Lisp-based but I need to mangle text a lot. elisp is from the same tradition as CL so it's pretty similar.
- Y_Y 1y agoTypical, asked for a tree and returns a flat list...
- rich_sasha 1y ago
- firemelt 1y agoI can't handle the line noise :(
- dusted 1y agoLooks great, I like the clean syntax and in particular the defn is pretty. I lost interest before I got to implementing proper functions, so mine only has variables that can be executed, if you're interested, it's here http://dusted.dk/pages/slispRepl/ http://dusted.dk/pages/slispRepl/ but it's a mess, and only interpreted.