Hacker News new | past | comments | ask | show | jobs | submit login
Janet – a Lisp-like functional, imperative programming language (github.com/janet-lang)
223 points by tsujp 6 days ago | hide | past | favorite | 134 comments





I am a happy though very new Janet user. I started migrating my existing workflow optimization scripts (e.g. Git wrappers) to--and writing new ones--in Janet as of a few months ago. I used to use Perl but I switched to Janet as it is a much simpler language and VM, and being a Lisp is ~infinitely extensible.

Janet has os/ and file/ packages, as well as a PEG system which mostly stand in for the best features of Perl. Some low-level POSIX-specific operations (like daemonizing and forking) aren't practical but I can just use C for those.

I am also using it to teach my son very simple programming. He can't type well yet, so the terseness of the language helps (there are cryptic symbols but he likes learning their names and how to type them). Its REPL and functional style I feel help a lot too.


I've played with the idea of converting my bash path scripts to Janet, but haven't had the time yet. Have you experienced any downsides of using it for your optimization scripts?

I would say that if you're interested, go for it.

My complaints about Janet are not too big. I feel like there are many ways to do some things, and they are all basically the same. Most of this excessive flexibility is inherited from Clojure.

1. It's never clear whether I need `cond` or can get by with `case` until I've waffled around a bit

2. I don't know whether to choose `if`, `and`, or `when`, for conditionals, because there are many times when all three would work. Also, if the condition expression is trivially negated (e.g. change '=' to '!=') then even `or` would work, making 4 choices.

3. It's hard to choose between `->` vs. manually-nested expressions.

EDIT: formatting


I'm pretty experienced with Clojure and here are my takes on those:

1. The Janet docs suggest `cond` as a replacement for if-if-else-else chains in other languages and `case` for `switch`-`case` blocks. That's a pretty good rule, although maybe you've already encountered that explanation? My main rule of thumb is that if the important value is "enum-y", representing a particular kind of thing or state, try `case`. If not, use `cond`. Neither Janet nor Clojure have enums (although you might be able to hack them in through macros or interop), so keywords usually serve that role.

2. I would prefer `when` to `if` because it's usually clearer what's going on. I usually don't use `and` in place of `if`. The trivial negation problem is an issue in basically any programming language that has `and`, `or`, and `not`, but it does add more options. Whether to use `and` or the equivalent `or`, I think your first instinct is often best.

3. I tend to favor threading macros (`->` and `->>`) when something is three or more functions nested and manually nested expressions for the rest.

For a total beginner, I would actually suggest forgetting about the more specialized options until you're comfortable. In other words, just use `cond`, `if`, and manual nesting. (Obviously still use `and` within the branches of `cond` or `if`.)


Thanks for the tips. I will try to keep these in mind so I can stop thinking so much about trivialities.

When I was using Java in my day job, I toyed with Clojure a bit and it was a pleasure. My favorite features were protocols and multi-arity functions.


This is solid advice. :)

I've also played with it but it's still feels like a toy language? Not particulary fast and also the messages are not particulary useful when you make syntax errors. Some aspects of it are nice though. If you come from imperative programming background, it's easier to write code in Janet compared to Scheme. Easier to use than Racket, but then again Racket has lots of features and libraries: PEG, regexps, pattern matching, you name it. So I feel like my time is better invested learning Racket instead?

I wasn't looking for something fast, as I'm happy to write some code in C anyway for something performance-sensitive, and most of the stuff I was going to write in Janet would be for interactive use. I was more interested in having a simple VM and a language that wasn't piling on new features every release like mainstream blub languages.

I also wanted a language that gave a straightforward mental model without an opinionated philosophy that tried to protect me from mutability and other real-world things (hence I didn't really want to go with Haskell and ~purely functional languages).

FWIW I also think the syntax errors in Janet are somewhat hard to grok.

  > So I feel like my time is better invested learning Racket instead?
I think it depends. If you want a language you can always rely on for 99% of use cases, something that covers many bases makes sense. For me, I wanted more of a fill-in-the-gaps language where neither C nor /bin/sh scripting make sense (e.g. stuff I may run on Windows or something heavy in string-handling).

> Janet has os/ and file/ packages, as well as a PEG system which mostly stand in for the best features of Perl. Some low-level POSIX-specific operations (like daemonizing and forking) aren't practical but I can just use C for those.

The README briefly mention the C API. How easy is it to use it, and how easy is it to "lift" results from the C API into Janet? (e.g. wrapping an fd from the POSIX API into a file object)


It's easy to treat any C struct as an abstract object in Janet, then have functions that do specific things (e.g. write to the file, read from it, etc). You have to write some manual code, but it's generally not too bad.

Good question :) I actually haven't had a good excuse to use the C API yet. When I need C I just code the entire tool in C, or use IPC.

Dumb question: Is IPC Inter-Process Communication? Or is it an unrelated tool?

> Is IPC Inter-Process Communication? Or is it an unrelated tool?

The former. Piping with the shell, or C subprocess hosted by the Janet script, or vice-versa.


Have you perchance tried Gerbil as well?

I did not hear of it before. Glancing at the website, it looks rather appealing (simple language, C-friendly FFI) but I don't see anything about using Gerbil in the shebang line for scripting purposes?

I may give it a closer look sometime.


Anything new happen with Janet?

https://news.ycombinator.com/item?id=28255116 (August 2021) [114 Comments]

https://news.ycombinator.com/item?id=23164614 (May 2020) [269 Comments]


Some interesting changes since August this year:

- Threaded channels `ev/thread-chan` (`thread` has been deprecated [and removed in latest version [[1.18]]])

- JPM (Janet Package Manager) is now separate, not distributed together with Janet anymore

- Janet binary can directly run image files with `-i`


(Not a lisp guy).

What is an image and why would I want to run one? My best guess is that an image would be platform independent bytecode vs compiled executable?


It's a dump of the state of the run-time environment, including data. Probably the easiest use case is using it as a savegame feature when you're working in the REPL.

It's not necessarily portable. Some lisps will use machine-independent bytecode, others use native code. I'm not sure which one Janet does.


I think of it as one of the defining features of Smalltalk, not Lisp, although there is plenty of cross-pollination.

https://en.wikipedia.org/wiki/Smalltalk#Image-based_persiste...

Janet's object system seems to be modeled after ideas first popularized in the Self language -- a Smalltalk derivative -- so there could be some direct inspiration there.

https://en.wikipedia.org/wiki/Self_(programming_language)


Lisp systems had it first, specially Lisp Machines, that is where Smalltalk got its idea from.

Xerox PARC was pursuing three workstation based OSes in parallel, based on Lisp, Smalltalk and Mesa (later evolved into Cedar).

So the ideas regarding images, REPL with typo suggestions, OS wide debugging, code browser,.... were available across them all.


LISP I from 1960.

http://bitsavers.org/pdf/mit/rle_lisp/LISP_I_Programmers_Man...

page 67: SET card

'...the state of the memory as it stands is read out onto tape 8 as the new "base" image for the memory...'


Damn, why don't we have programming environments with such capabilities today? (the kind @pjmlp mentioned "images, REPL with typo suggestions, OS wide debugging, code browser", etc." and so on)

Not in the @pjmlp kind of availability ("Why you say that? There's this commercial language envinronment from a company in rural Austria that all of 100 companies use and all of 1000 people ever heard of that gives you exactly that! A 2-person department in the basement, right across the toilets in Jane Street uses it for something. And somebody made a weather balloon controller with it. Plus some mid-90s research team had this in some research language that has these features, that over 10K students have installed!").

Not even in the Pharo, SBCL, etc. kind of availability.

It would nice to have it in the "competes with Java, C#, Python, Javascript, PHP" or at least Go and Rust, for popularity, adoption, libraries, websites and sources devoted to it, job opportunities, vendor support, enterprise adoption, and such" kind of availability...


Because those features cost money to develop, and plenty of developers nowadays want to be paid, while refusing to pay for the work of others.

So you get what is possible with long nights, weekends and abandoned university thesis after graduation, instead.


>Because those features cost money to develop, and plenty of developers nowadays want to be paid, while refusing to pay for the work of others.

Yes, but v8, Grail, the JVM, .NET takes lots of money to develop as well. Even Swift (despite Apple being stingy, so that is probably just a 5 person team force-fed Jolt Cola) costs a lot. But companies seem to pay for those, but not for those other styles/features.

To be frank, even if we had this technology, but it was a closed source, proprietary affair, I wouldn't want it anyway. That's another must-have feature in 2021 - and it's not just about "not wanting to pay" (I pay for IDEA subscription, for example). It's about what such a license would mean for corporate adoption, ability to tinker with it, reliance on a single vendor, and so on.


My take is that this feature is fundamentally at odds with how most programming languages work.

For starters, I think that it's probably no accident that you generally only see these image-based development features in dynamically typed languages. For image-based development to make sense, you really want to have long-lived interactive sessions. In Smalltalk, they are effectively endless, and can span multiple decades and branch among thousands of people. In a static language, though, you've got an incentive to keep your interactive sessions short and do most of your development outside of it, because code changes inside the interactive session can lead to weird chicken-and-egg problems.

Second, there are some real ergonomic challenges. It's easy to get into a state where what you're doing isn't reproducible, because there's not necessarily any paper trail on how to rebuild the current state from scratch. This is a famous criticism of Microsoft Excel - arguably the world's most widely used fully interactive development environment along these lines - and a major reason why a major project at of one of my previous jobs was to replace one department's suite of heavily scripted Excel spreadsheets and replace it with a C# application. The company was rightly concerned that they were one file corruption away from a major business disruption. Similar criticisms, albeit on a less operatic scale, are often leveled against Jupyter notebooks, which aren't quite the same thing, but to retain many relevant features.


> … there's not necessarily any paper trail on how to rebuild the current state from scratch.

Yes there is!

"As you define and modify classes or methods, Smalltalk/V is logging all of these changes to the change log.

Every Smalltalk expression that you evaluate with either do it or show it is also logged. In addition, every time you remove a method from a class, a message is logged."

p282 "Automatic Logging of Changes"

https://rmod-files.lille.inria.fr/FreeBooks/SmalltalkVTutori...


> For image-based development to make sense, you really want to have long-lived interactive sessions.

Not really — most people get into a dreadful mess when they try to do that.

For most people, it works better to version and export discrete change-sets.

It makes sense to be able to save the state of your work, go to lunch, and pick up in exactly the same place when you come back.

It makes sense to be able to save the state of your work, go home, and pick up in exactly the same place when you come back the next day.


> Damn, why don't we have programming environments with such capabilities today?

Do you use any of the image based programming environments that we do have? Pharo? VM Smalltalk?


When folks run emacs, they aren’t actually starting it entirely from scratch. They are booting up a similar “image”, which allows for much faster startup.

The lack of image support is what prevents Clojure from competing on startup time (but see also grallvm and babashka)


There are also the JIT caches on HotSpot, OpenJ9 and Azul.

R for example allows to save state on exit. I wish R supported an alternative lispy syntax.

I'd never heard of it until https://news.ycombinator.com/item?id=28845971 was shared here yesterday. I guess I'm not alone in just finding out about it and that's why it's posted here.

This is one of those languages I'd like to try because the people I know of that are using it seem so dang happy.

Start by browsing some of the user submitted examples over at https://janetdocs.com/

Congratulations on it. I use Common Lisp myself, but always great to see energy and passion in other languages, especially in the Lisp family of languages (but I am clearly biased).

This looks really interesting, going to check this out later today. Anyone using Janet for anything that would care to comment on their experience?

I'm making an editor, Freja, which is like a tiny Emacs with graphical support. Makes it fun to create gui apps and games. :)

Ultima Underworld inspired game I'm making for a game jam: https://youtu.be/1fWsV83P-S8

Demo of pixel editor: https://www.youtube.com/watch?v=KOBi805nxNc

Freja: https://github.com/Saikyun/freja

---

My experience has overall been very nice. I come from Clojure, and comparing to that:

- so nice and small! Clojure is great but has a lot of baggage from JVM, for good and bad

- very easy to get started interoping with C. You need to manually wrap libraries, but I think it's pretty easy. As a benefit, you are able to throw exceptions from C that can be catched from Janet. The C support is what sells me on Janet over Clojure

- repl:ing works well, but you can get tripped up by early binding and lack of namespaces. There are ways around it, but when coming from Clojure it was a bit hard to wrap my head around

- many libraries that you'd want are already wrapped, like http-servers and postgresql connections. But ofc this is an area that is thinner than older languages. It's decently easy to wrap C-libs though

- easy to understand data structures if you've used JS / Lua -- "everything is a hashmap" (but there are also arrays and strings)


Freja looks really cool! Thanks for sharing it. I find these types of projects very inspiring. They bring back the wonder and joy that I felt when I first discovered computers in the early 80s. You felt like you were in control of a whole new world and anything was possible.

Thank you! That is exactly what I'm going for. :) My friend said "so you're just making basic?", haha.

I didn't get to experience C64 / Amiga era, but after having listened to 100s of interviews with swedish game developers it seems that the automatic (or even required) access to a coding environment sparked a lot of creativity and imagination. :) I hope Freja can capture at least a part of that.


Wow! Some really cool projects, thanks for sharing, I'll definitely check out Freja later this evening!

Thanks so much for the info and commentary!


Thank you. :)

If you do try it out, I'd be happy for any feedback on Freja! :)

I should mention that Windows support is currently a bit behind, so if you're on Windows I could fix that then comment here again when it's done. :)


Why do you mean by ‘throw exceptions from C’? C has no exceptions.

In libjanet you can use a C call like janet_panic() that'll "panic" and throw an exception/error up in the active Janet runtime (so when something bad/unexpected happens in your C code you are providing an API to from Janet, you'd use this).

This is what I was referring to, sorry for being unclear. :)

That is like saying Scheme does not have exceptions, except in C, we have setjmp instead of call/cc. It is technically correct, but there is something more flexible that can be perverted into doing the same thing.

https://en.wikipedia.org/wiki/Setjmp.h#Exception_handling


I've been writing about my first impressions of the language here:

https://ianthehenry.com/posts/janet-game/

Not a whole lot of content yet, but I plan to keep going with it.

I am pretty firmly in the Haskell/OCaml "let me program with types" camp for most development, but it's a great to have a little scripting language to reach for instead of bash or Python or Perl. Using Janet (coming from Python) reminds me a bit of:

https://xkcd.com/353/

Except... without the rich standard library :)


Thanks for the link, I'll definitely check it out! What actually piqued my interest was the surface impression of something like a Lispier Perl/Python.

Your writing style is really enjoyable, I binged the 3 posts and really enjoyed, especially the macros post

I've thought about using Janet for a game, but there's more examples of people using love2d plus Fennel so I'm more likely to use that combination for my future Lisp game experiments. (Fennel is similar to Janet and created by the same person, but compiles to Lua.)

I wrote a few websites with it, notably:

https://github.com/swlkr/janetdocs

I also scraped together a large web framework and a small one:

https://github.com/joy-framework/joy https://github.com/swlkr/osprey


I'm using your html library (a Clojure hiccup clone, sort of) and tw (tailwind) library, and often use janetdocs to find examples of how to use Janet functions. Thanks a lot man!

Hey! It's nice to see someone using the stack!

What's funny about tw is that it was kind of like a ghetto tailwind jit before it was released!

Janet can really help you move fast


Haha, I like that description: "ghetto tailwind jit".

From your blog it seems like you're not really using it yourself anymore, though?

I tried to add a styling thingy (sorry, really not familiar with the terminology) to `tw` to add support for "print" media queries (like this: https://tailwindcss.com/docs/breakpoints#styling-for-print), but didn't get it to work on the first try. If I do make it work I'll create a PR :)


Oh yeah, that's a bit of journey, each variant is kind of annoying to handle manually.

I always look forward to any and all PRs!

Edit: Yeah I haven't used it lately, I currently use roda + sequel now (ruby libraries).

I have limited time after work and I really want to get some "SaaS apps" up and running, so the trade-off was spend less time on libraries and more time on applications.


Because swlkr is a bit modest, I’ll take this opportunity to point out his Janet twitch streams on his behalf. Definitely check them out! (google for “twitch swlkr”)

haha thanks for the shout out!

I’m currently working on ruby stuff on stream but maybe I won’t be able to stay away from Janet for long


Thanks for all of your work Sean. I've messed around a bit with Joy and have been keeping an eye on the development of the framework.

Hey no problem! It's always great when something I make for myself works out for someone else too!

Oh awesome, thanks for sharing, I have already been looking at some community examples on there!

I use Janet most often as a glue for shell utilities using the sh package (https://github.com/andrewchambers/janet-sh). It's a great tool for building small containerized jobs. I think it has a ton of potential as the ecosystem grows and matures.

Some rough spots:

- No canonical http client. There are a few attempts at wrapping libcurl but nothing complete and well documented yet. However, the creator of Joy framework for Janet does have an http client library.

- The main http server circlet is MIT licensed, but it is built on top of Mongoose, which is GPL/paid commercial. Something to be aware of if you want to distribute binaries made with this library.

- I have never been successful getting any of the UI or drawing libraries to work.

- Naming of packages is a bit confusing even if you have watched the Good Place and are aware of all of the inside jokes.


> I have never been successful getting any of the UI or drawing libraries to work.

Have you tried jaylib (built on top of raylib)? I have gotten that to work well on macos, linux and windows. :)

> The main http server circlet is MIT licensed, but it is built on top of Mongoose, which is GPL/paid commercial. Something to be aware of if you want to distribute binaries made with this library.

While I haven't used it outside of development, chidi is MIT licensed. :) https://git.sr.ht/~pepe/chidi


When I tried to use jaylib I was not able to get it to work at the time. Might have to give it another shot.

The http server used in Chidi is actually fairly new and I was not aware of it. It is part of the spork package. About two months ago I chatted with the creator of Janet about whether or not an http server will be added. He said it would not be added to core, but it looks like he added to spork about a month ago. It looks like it is a pure Janet implementation so there should be no licensing conflicts. I'll have to try it out.


I know I had some trouble with raylib's dependencies on Linux. If you get stuck, feel free to at me at the janet gitter.

Will do, thanks!

The Mongoose github says it's MIT Licensed https://github.com/Automattic/mongoose

Different mongoose in this case: https://cesanta.com/

Doh!

I'm using it for some side projects, combined with htmx (htmx.org).

What I like:

1. The applications start really quickly, compared to Clojure.

2. It feels like I could learn everything about the language if I ever want to dive into the internals. With Clojure/Babashka I don't think that would be possible for me.

3. A bit vague, but it really feels nice to program in this language. I can easily get things to work, I can mess around in a REPL if I want to, and #4:

4. The community is great. Instead of searching on the internet, when I don't know how to do something, I ask a question on gitter / matrix and before long there's an answer from a more experienced person (sometimes even from the creator of the language).

5. The package manager (JPM) is really easy to use.

6. In terms of download size, Janet it tiny. But compared to Lua, it's way more "batteries included" due to the great standard library.

What could be better:

1. Tooling I guess, but that's logical for younger languages. I use Olical his "Conjure" Neovim plugin, which is great. I don't think it's possible to jump to the definition of a function name if my cursor is on it. Maybe that's normally done through LSP in Conjure, I'm not sure. I don't know if there are plans to add LSP support to Janet?

2. I just found out a couple of days ago that Janet has no `set` datastructure. You can work around this by using a hashmap where each key maps to a value of true, or you can use a library that adds the datastructure.

3. Not sure if this would have downsides in Janet, but something I really like about Clojure is that you can use a lot of standard library functions on all data types. In Janet sometimes you have to look up a function specific to a data type, where Clojure would be more agnostic - with functions that work on different datatypes in an expected way, and return a `sequence`.

4. Some library authors have the tendency to use "The Good Place" references in their library names. I know the name "Janet" is a reference to that series, and I know developers in all languages are always trying to be funny. But finding a library called "html" (by swlkr) is way more helpful than finding one named after some character from a series.

What I think I will like, but haven't tried yet:

1. Object Oriented Programming in Janet seems nice (https://janet-lang.org/docs/object_oriented.html).

2. PEG (Parsing Expression Grammars - https://janet-lang.org/docs/peg.html )


> Multithreading

Does it have a global interpreter lock (GIL)?


> Each thread has its own Janet heap, which means threads behave more like processes that communicate by message passing.

https://janet-lang.org/docs/threads.html

Janet doesn’t seem to have shared-memory multithreading. Each thread runs independently, so a GIL should not be necessary.


Though you can share memory manually, i.e. in C but access it from Janet.

I wrote similar here: https://github.com/ahungry/janet-pobox although it probably needs updates to work with 1.18 and above.

Oh, that's really cool. :) Thanks for mentioning it.

What's the advantage of not having lists? How does this affect one's programming style versus Scheme or Common Lisp (or Emacs Lisp, honestly the Lisp I'm most familiar with)?

Disclaimer: I've never used Janet, but I am pretty familiar with Clojure.

In Clojure, there are lists, but the most common structure for sequential data is actually a vector [1], which works more-or-less as a slightly modified version of the Clojure version of a hashmap. Advantages of doing it this way is that you get log32 indexed lookup times (vs linear for lists), and you also get log32 [2] append-to-the-end semantics instead of "push to the beginning" that you have with lists.

In practice it generally doesn't affect a lot, but occasionally when I do need to put an item in the front of a collection, I will wish I had used a list instead of a vector, but I feel like the far more-common usecase is to append to the end, since in Erlang there's been a few times where I end up having to reverse the list after I'm done building it.

[1] At least how I use it, I haven't done any statistics to prove this.

[2] Don't let the log scare you! Log32 is very good and also effectively constant time for most in-practice use cases. Log32 of a billion is basically six, meaning you're dealing with a constant factor times six hops for inserts and lookups on a billion elements.


Phil Bagwell's VList data structure seems really interesting as a way to avoid a bunch of the pitfalls of naive lists performance-wise - the paper's good fun and there seems to be an implementation in racket for anybody who wants to play with it.

The problem with a vlist is that it doesn’t maintain lisp list semantics. You can’t implement setcdr on a vlist. But you can with something like cdr-coding.

The paper discusses how to handle appends and similar.

Assuming the majority of your lists are read-only apart from appends, you can end up with something pretty performant overall.

Trade-offs all the way down as ever though.


Does any one have a copy of anything related to this?

Wikipedia had an article on it deleted, and I'm not getting much from the first few pages of google...


Racket implementation: https://docs.racket-lang.org/functional-data-structures/VLis...

There's a copy I made of the original paper here: http://trout.me.uk/lisp/


You can access any element in your array in O(1). I think it is faster to loop through as well, but I'm not so sure about that.

The drawback is that appending / removing elements at the beginning of the array is O(n).

When it comes to interacting with the collections I mostly use the loop / seq macros, which I believe are pretty similar to Common Lisp. Ofc you also have map / filter / reduce.


Why use this over Chicken Scheme?

I'm unqualified to answer since I haven't used Chicken Scheme, but the name implies that it's a Scheme, right? Janet is a "modern" lisp-like with [] and {} for arrays and maps. Also, I think Chicken compiles to C? Janet compiles to bytecode.

A copy-paste from "Use Cases" in Janet's README.md:

Janet makes a good system scripting language, or a language to embed in other programs. It's like Lua and Guile in that regard. It has more built-in functionality and a richer core language than Lua, but smaller than GNU Guile or Python.


Chicken Scheme also makes a good language to embed in other programs. As does Gambit.

They are Schemes though.


I like using Hy for these use cases. Because it gives you access to all of the Python module ecosystem while staying in a Lisp-like language.

While we are at this topic: why use Chicken Scheme over this?

Decent amount of libraries (eggs) for one(and a package manager). Follows a language spec (R5RS).

Then we get to the personal preferences territory. You may prefer a Scheme(with its hygienic macros and other goodies). Or the way it generates C code (which is then compiled).

As an example. At one time I was experimenting with writing iOS games in Scheme. The usual option would be cross-compilation. I would cross compile my Scheme program as a library and add the to project. But XCode is annoying because it wants ARM code for the actual device, and X86 code for the simulator. Rather than building a complicated build system, I just told Chicken to stop at C code generation, then added the generated code to the XCode project. XCode could now compile the entire thing as if it was all C+Objective C code in the first place. Add a couple of instructions for the actual embedding and there's my hybrid Scheme+Objective C program.

Related to the example above, I was missing an OpenGL ES library. But I found a similar library from Gambit Scheme. Given that they are both Scheme, the code would work with almost no changes. The only changes were related to the foreign function interface (to call C), which were not standardized. So I just wrote a 'compatibility' macro, and the code would now run.

Ultimately though, it's all up to you. I'm just happy there's always some healthy baseline interest in Lisp-like languages.


or, maybe newLISP and vice-versa


I would like to have a language like this that is easy to bind C++ (including classes) code to in a way as easy as ChaiScript.

I did several experiments for a side-project. The end result was that I moved from ChaiScript (no generators or fibers or lightweight concurrency) to Wren language.

I saw Janet, and I was very tempted, but nothing like WrenBind17 exists for it AFAIK.


Wonder given it is easy to be embedded, will we have an iOS janet app?

You can build Janet in iSH and run it on an iPad that way, which is what I do.

Maybe I'm just too pedantic, but this is not a functional language. Yes, you can write functional style code, but you can write functional style code in C, C++, Java, Python, JS, Ruby, Common Lisp, Scheme, etc etc. That does not make any of these languages 'functional'.

> Yes, you can write functional style code, but you can write functional style code in C, C++, Java, Python, JS, Ruby, Common Lisp, Scheme, etc etc. That does not make any of these languages 'functional'.

Lisp-family languages (both CL and its immediate predecessors, and Scheme) for a long time were the textbook example of functional languages. The relatively novel (and still niche) attempt to redefine things so that only pure functional languages are “functional languages”, and particularly the people that insist on this usage as if it were firmly established and abuse those who don't conform to their preferred redefinition, is a bit annoying.


This is not correct, lisp operations on lists have always been to modify in place, with copying versions added later. The technology did not exist to do functional programming efficiently enough (and to some extent that technology still does not exist generally).

Simply false. For example, LISP 1.5 manual had this definition for UNION:

  (union (lambda (x y) (cond ((null x) y) ((member
         (car x) y) (union (cdr x) y)) (t (cons (car x)
         (union (cdr x) y))))))
It had a MAPLIST (today called MAPCAR):

  maplist[x;fn]=[null[x]->NIL;
                 t->cons[fn[x];maplist[cdr[x];fn]]]
Or APPEND:

  append[x;y] = [null[x] -> y; T -> cons[car[x]; append[cdr[x];y]]]
Et cetera. Sure, it also had, say, NCONC. But it had these operators and style from the beginning, not surprisingly, as Lisp came from lambda calculus.

Only for those revisionist folks that have decided Haskell is the baseline for FP.

Functional doesn't really have a consistent definition, and you end up always with "yeah but"s in any discussion e.g. haskell isn't functional because C ffi and unsafePerformIO.

Point being, its very hard to say "X is or is not functional", as there isn't an objective consideration.

(FYI, I love Haskell and use it daily and write it professionally)


This language has mutable strings. This is in some sense the opposite of functional style.

So for me the primary qualifier is “are functions first class”; then “can functions be defined like data” (lambda); then “does it have a rich library of functionality that allows one to program functionally with it”; then “Is fp style idiomatic” ; then probably “does it have a good method to control mutability”; then “does it control side effects”

There may be some other examples in there. Personally I like things with controlled side effects. But it’s just my preferred set of trade offs.

Anyway I mean its just tough to be dogmatic about it. I get what you’re saying but why is that the dividing line?


Functional style does not allow for 'evolving' a value in multiple steps. In some sense this is the heart of the difference between functional style and other styles of programming.

Language features which are only possibly used in a non-functional style make me want to say that describing the language as 'functional' is either wrong or saying a language is 'functional' is a meaningless claim. If every language is functional, saying it is completely redundant.

I like your idea of saying FP style is idiomatic in that language might qualify the language as being described as 'functional', which I think agrees with my intuition that mutable strings being built in is evidence that calling that language 'Functional' is misleading or silly.


The main question for me is whether it has persistent data structures with structural sharing. If it has that, I'm happy to call it "functional." Without that it's hard to write efficient pure functions.

I've noticed that the language inspires how people write code, and the community.

Sure you can write functionally in Python with generators, first class and higher order functions, but its not really how the community writes (all the time).

Scheme isn't pure functional, it is mutable, but people write _as if_ it is immutable.


Is this Scheme/Common Lisp? Where are the cons cells?

Nope. There are no cons cells here.


Off topic: Is it just me or are there any others who find naming programming languages with women's names a bit weird?

Julia, Janet, Eve...

I understand the guy referring to his car as his "girlfriend" and give it a women's name. I just can't feel the same about tech.

I guess this may be the nerd's way of immortalizing their sweetheart, but if I was a woman I'd rather prefer to be a car and not a programming language.

A programming language doesn't feel much anthropomorphizable to me, let alone lady-like.

Women, what do you think?


Not named after a woman (or rather, named after not-a-woman): https://github.com/janet-lang/janet#why-is-it-called-janet

>not-a-woman

given that the character of the show in question is an archetypal secretary arguing it's not a woman is a fairly big stretch. Not only is it a woman, it's a woman embodying a female stereotype, (in line with the purpose of the language, being an easy helper), and the 60s art deco woman's magazine style logo


Can’t decide if “if it looks like a female secretary then it’s a woman” is progressive or backwards.

I suppose that depends on whether you think women should be doomed to the role but it takes some extraordinary imagination to pretend the stereotype doesn't exist, or that one gets around it by making the woman in question an artificial one

kinda like if I made a software called arnold with a picture of he-man as a logo I doubt one would be considered backward for thinking I had a guy in mind


Calling working as a PA "doomed" is probably the most offensive thing said yet in this thread.

Janet is canonically not a woman. It is said many times. Also not a robot.

No, I don’t think that giving non-objects/not objectifiable things women’s names is weird. Nor that the necessary implication is that they are named after girlfriends.

It's like naming boats after women. A recognition of the distinct nobility and beauty of women our culture has lost track of.

Ada, Alice...

Interesting question, but it might just be a yellow volkswagon effect. Quickly looking at Wikipedia's list of languages, theres Babbage, Bertrand, Cecil, Darwin, Dylan, Escher, Euclid, Euler, Godel, Hume, Orwell, Tom, Zeno, and probably a few others I missed.

EDIT: Haskell and Pascal, how embarassing to miss those


It is interesting that female-named languages from your examples generally use first-name, while male-named languages generally use surname.

I was first introduced to programming with Pascal, can't believe I forgot about it until I saw your list.

> Haskell and Pascal, how embarassing to miss those

and Curry, while we're at it, https://curry-lang.org/


also Haskell and Pascal

It's a shame that Haskell Brooks Curry did not have any more names because all three of his names have already been used for programming languages by now.

I also like to believe PageRank was named after Larry Page.

> I understand the guy referring to his car as his "girlfriend" and give it a women's name. I just can't feel the same about tech.

Why do you assume programming langauges with female coded names are because the creator is viewing it as a girlfriend?

Not all creators are heterosexual males (or otherwise oriented toward females as preferred or even acceptable romantic partners), and even those that are don’t necessarily view women exclusively through the lens of romantic involvement such that that would be the implication of a female name. Also, not all female-coded names are actually female in reference (Janet is named after a character that is expressly not a woman.)

> A programming language doesn't feel much anthropomorphizable to me, let alone lady-like.

Why “let alone lady-like”? Why are female-coded names a particular issue, if the problem is that programming languages aren't “anthropomorphizable”? (I don't actually think naming things after people is inherently about anthropomorphization; we do it to freeways and bridges and other things as an honor, not as anthropomorphization.)


> Why do you assume programming langauges with female coded names are because the creator is viewing it as a girlfriend?

I am not assuming that. I was just comparing it to the situation with cars.

> Not all creators are heterosexual males (or otherwise oriented toward females as preferred or even acceptable romantic partners), and even those that are don’t necessarily view women exclusively through the lens of romantic involvement such that that would be the implication of a female name.

I wasn't implying such a thing. But I knew a woke person was going to point it out to me anyway. Funny.

> Janet is named after a character that is expressly not a woman

The logo of the programming language is the face of an attractive woman wearing a lipstick and a fancy hairdo. Also, Janet is portrayed by a woman in the Good Place. Don't tell me that the name of the language has nothing to do with a woman.

> Why are female-coded names a particular issue

I don't think it is an issue. I was just thinking out loud.

Take it easy.


> I am not assuming that

Well you did say: "this may be the nerd's way of immortalizing their sweetheart", which seems to me to strongly imply that your impression may be closer to assuming it than to not assuming it.

I have no horse in this race (I'm not the one who replied to your original comment), but it did seem like you were assuming something awful close to what you are denying.


In my world saying that "something may be something for other people" doesn't equal to "personally assuming that something is something". But I understand where you come from.

For me the thinking & debating exercises doesn't have to involve taking a position personally. Sometimes I just want to focus on the argument. My own position & assumptions are irrelevant.

For that reason I don't appreciate it when somebody makes an assumption regarding my assumptions to attack myself instead of focusing on the argument.


I don't see anything in dragonwriter's response that attacks you and not your argument. Perhaps you just disagree with the phrasing, but to me, "you assume" in this context is short for "you assume in your argument" or "your argument assumes" and it still looks valid.

> "you assume" in this context is short for "you assume in your argument" or "your argument assumes" and it still looks valid

An argument doesn't assume, but it states. Assumption is something people do. When somebody makes a statement regarding "what an argument assumes", the meaning is that they are speculating beyond what the argument is stating.

So I don't agree with you, but thank you for the discussion.


An argument assumes if it doesn't back up the assertion with reasoning. For an argument to state, it needs more; as written, it wasn't really an argument to begin with. It was just a theoretical supposition.

Yes, I guess mine was more of a theoretical supposition. It was actually just an observation. Yet a moment later I wasn't really talking about that anymore, but making a more general statement regarding the exercise of debate.

Thank you for playing the role of the logic police. I guess it can sometimes be unreasonably hard to talk in a simple forum like this in a chill manner without having to deal with people's (IMO) misplaced pedantry. So be it. I'll try to be more scientific the next time.


Hey, I'm just trying to explain what your comments look like to someone not involved in the original conversation, since I agreed with the statement that you objected to. Not sure where this passive aggressive defensiveness is coming from.

The julia language is claimed to not named after a woman, and it's considered to be against the community code of conduct to anthropomorphize it. People calling julia their girlfriend get asked to stop pretty quickly.

I mean, this is done well outside programming languages. See; for example, tropical hurricanes.

That used to be true, but hurricanes haven't been named exclusively after women since 1978.

> The practice of naming hurricanes solely after women came to an end in 1978 when men's and women's names were included in the Eastern North Pacific storm lists. In 1979, male and female names were included in lists for the Atlantic and Gulf of Mexico.

https://www.nhc.noaa.gov/aboutnames_history.shtml




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: