19 ms·
Why Fennel?
- iLemming 3y agoIf you're using a Mac, maybe check this out https://github.com/agzam/spacehammer https://github.com/agzam/spacehammer
- robertlagrant 3y ago> Another common criticism of Lua is that it lacks arity checks; that is, if you call a function without enough arguments, it will simply proceed instead of indicating an error. Fennel allows you to write functions that work this way (fn) when it's needed for speed, but it also lets you write functions which check for the arguments they expect using lambda. I don't understand this; why is this a speed consideration?
- iimblack 3y agoI think they meant speed of implementation.
- rpdillon 3y agoI'm not an expert, but my understanding is the Lua has a very limited grammar that is specifically designed to be parsed in a single pass. This precluded Lua from performing arity checks on function calls. Fennel does support arity checks but it comes with a runtime cost since it's implemented as a separate Lua call after being transpiled from Fennel.
- deleted 3y ago[deleted]
- vore 3y agoThe grammar shouldn't have anything to do with arity checking – at runtime, you're going to know if you passed a function 2 arguments or 3 arguments, and due to the presence of dynamic evaluation, knowing how many arguments a function takes is not statically knowable anyway. My best guess is that they want to avoid the overhead of a runtime check for arity.
- bnert 3y agoArity explanation: https://en.wikipedia.org/wiki/Arity https://en.wikipedia.org/wiki/Arity From the blurb you quoted, it sounds like Lua doesn't check function argument arity natively, and fennel can. This means that fennel applies a runtime check to validate if a function was called with an expected arity, and if not, propagates an error (however Lua does that, I do not know), hence why arity checked functions are not as performant.
- nmz 3y agoSo it basically does function M(...) if select("#",...)>3 then error("failed arity check on M()") end end
- ravi-delia 3y agopretty much, yeah
- gumby 3y agoMy memory of this is hazy, in part because I wasn't a C programmer in those days, but ISTR C used to do this too. I think prototypes were added (and required) only by the time ANSI got involved. Maybe some other OF can confirm/contradict?
- ahoka 3y agoFun fact: in C, if you have a signature like “int foo()”, it means any number of arguments can be passed (vs “int foo(void)” which means no args).
- fulafel 3y agoAnd there is no way for the callee to check the nr of passed args, unlike in Lua.
- sovietswag 3y agoGood reference for that: https://jameshfisher.com/2016/11/27/c-k-and-r/ https://jameshfisher.com/2016/11/27/c-k-and-r/ This was also used to implement variadic functions like printf before varargs, see https://retrocomputing.stackexchange.com/a/20517 https://retrocomputing.stackexchange.com/a/20517
- mdaniel 3y agothat's ... (amazing|C for ya) int foo() { return 0; } int main(int argc, char* argv[]) { return foo("alpha", "beta", 1); } $ gcc-13 -Wall -Werror -o foo foo.c # oh, sads $ clang -o foo ./foo.c ./foo.c:5:34: warning: too many arguments in call to 'foo' return foo("alpha", "beta", 1); ~~~ ^ ./foo.c:5:15: warning: passing arguments to 'foo' without a prototype is deprecated in all versions of C and is not supported in C2x [-Wdeprecated-non-prototype] return foo("alpha", "beta", 1); ^ 2 warnings generated.
- deleted 3y ago[deleted]
- astrange 3y ago
- munificent 3y agoCaveat: I haven't used Fennel but just inferring from what makes sense... The Lua VM that they compile to already handles missing arguments with some attendant but unavoidable performance cost. Fennel's own `lambda` form that they layer on top does check for missing arguments, but it must do so by generating extra Lua code to do those checks. That additional code has a runtime cost. Using `fn` avoids that extra generated code and its cost. If Fennel had its own runtime and VM, then the performance story for how missing arguments are handled would be different.
- mpenet 3y agoBecause it’s an extra runtime check vs a direct lua call
- Joker_vD 3y agoIIRC (and I remember it quite vaguely from some random blog post on the Internet) the Lua implementation uses some trick that greatly speeds up setting up and tearing down activation frames (and has also something to do with the ability to easily cross-call into C back to Lua again?), but it hinges on that argument-passing/result-returning semantics being "use nils for missing stuff, throw away the extras" so e.g. Python can't use it to speed up its implementation of function calls. Unfortunately, I can't find that blog post so take my words with a grain of salt.
- throwway120385 3y agoThis is mostly based on my experience in the past with Lua circa 2015 when I developed a GUI using Crank Storyboard Engine and needed to write some stuff in C because the Lua equivalent code was too CPU-intensive. If I remember correctly, Lua is a stack-based VM. What this means is that every piece of data has a corresponding location on a stack data structure in-memory. Function arguments are pushed into the stack as-needed and popped in the function context, and vice-versa for the function return values. If you wanted arity-checking in this context, you'd have to confirm that you got exactly the right number of elements on the stack, meaning there would be an extra branch in every function call. This might reduce performance if the branch predictor gets it wrong. Plus there would need to be extra instructions to count and to check the count for each pop off the stack in the context of the function call. This is from the perspective of calling C functions in Lua, so it's probably more complicated for the VM itself when it's running native Lua code.
- Verdex 3y agoLua is a register based VM.
- neutrono 3y agoI think he means that the C API is stack based?
- brennopost 3y agoIt was stack based before 5.0
- sullyj3 3y agoIt's a runtime check. The following fennel: (fn add-1 [x] (+ x 1)) (lambda add-2 [x] (+ x 2)) transpiles to the following lua: local function add_1(x) return (x + 1) end local function add_2(x) _G.assert((nil ~= x), "Missing argument x on /home/sullyj3/tmp/fn-vs-lambda/fnl/x.fnl:3") return (x + 2) end return add_2
- robertlagrant 3y agoGotcha - thanks!
- oedo 3y agoDeclaring a function with `lambda` prepends runtime nil checks for each argument to the function body (excluding optional args-- specified with a question mark, eg. `?x`-- and variable arguments, eg. `...`[1]). This Fennel: (fn foo [x y ...] (print x y ...)) (lambda bar [x ?y ...] (print x ?y ...)) ...transpiles to this Lua: local function foo(x, y, ...) return print(x, y, ...) end local function bar(x, _3fy, ...) _G.assert((nil ~= x), "Missing argument x on test.fnl:3") return print(x, _3fy, ...) end [1] Fennel's alternative `& xs` vargs format does create a runtime check in functions declared with lambda, but it always evaluates to true because it simply nil-checks the table (here `xs`) that it dumps Lua `...` vargs into.
- Graziano_M 3y agoI moved my Neovim config to fennel and haven't look back. https://github.com/Grazfather/dotfiles/blob/master/nvim/fnl/core/init.fnl https://github.com/Grazfather/dotfiles/blob/master/nvim/fnl/...
- ducktective 3y agoSo basically Emacs with Elisp replaced with Fennel and a more responsive UI...
- packetlost 3y agoEmacs is a whoooooole lot more than an editor and Lispy config language.
- thih9 3y agoWhat else is there apart from an editor and a lispy config language? I always thought of emacs as that, i.e. an editor that is extensible and dev friendly (in contrast to vimscript). I don’t know much about emacs though, so this got me curious.
- MassiveBonk51 3y agoWell the famous joke is "Emacs is an OS that lacks a decent text editor." (Yes Evil mode exists) Emacs can do basically anything you write an extension for it to do. It can be your calendar, your email client, your rss reader or even your git gui on top of being an editor. Emacs can do so much that it's daunting to start using.
- trenchgun 3y ago> Emacs can do basically anything you write an extension for it to do. It can be your calendar, your email client, your rss reader or even your git gui on top of being an editor. Emacs can do so much that it's daunting to start using. Vim can do all of those things.
- timetraveller26 3y agoI've been wanting to give Fennel a try, currently I use Moonscript for my Lua transpilation (https://moonscript.org/ https://moonscript.org/), but it has some criticisms and it can be a bit confusing sometimes.
- JNRowe 3y agoI'm a big fan of moonscript, but occasionally wish it was still being improved and worked on. Yuescript¹ looks like it fixes most of my bugbears with moonscript, and is for the most part a faster² drop-in replacement. There was s little discussion here ~18 months ago³, but it will feel largely circular if you look at it as people are suggesting fennel there ;) ¹ https://github.com/pigpigyyy/Yuescript https://github.com/pigpigyyy/Yuescript ² This probably only matters if you have tonnes of moonscript, not just a little neovim/mpv/awesomewm config or something. ³ https://news.ycombinator.com/item?id=29903133 https://news.ycombinator.com/item?id=29903133
- lc9er 3y agoAre you using Moonscript for nvim config or something else?
- timetraveller26 3y agoI use it to write my awesomewm config
- eviks 3y ago> yet keeps a very small footprint both conceptually it's only a benefit for writing simplistic things (and configs for some complicated programs like a text editor or a terminal or some MMORPG is already not simple), otherwise you start appreciating that there is not just a single dictionary as a data type etc.
- uwagar 3y agobecause its good for digestion
- giraffe_lady 3y agoI always say this when it comes up but fennel is very very impressive as a language project. Lua is much beloved but my professional experience is that working with it gets gnarly much faster than most other languages. Fennel focuses on a small set of the worst lua issues and addresses them without getting distracted or bogged down in language design extravagances or lisp nerd semiotics. The decision to strictly adhere to lua runtime semantics was initially repulsive to me, but I've come to appreciate the incredible wisdom of that approach. The practical experience of using lua is that because of the constraints of the language, every lua runtime is in some ways custom & unique. This decision of fennel's creator allows you to drop fennel onto any lua codebase, of any version, with any amount of custom freak shit grafted in, and just use it. Not only use it, but hook its compiler into the lua module loader system, and freely & transparently mix functions and tables between the two languages. A life raft in decrepit legacy lua codebases. The restraint and technical focus of this language led to me checking out janet, another project of its creator. I've also come to really like that language, it makes some similarly minor-seeming but brilliant decisions like including PEGs in the core lang instead of regex. Anyway try fennel, if you have to interact with a lot of lua pattern match alone will improve your life. Try janet too it's cool.
- throwawaypml 3y agoI think Fennel and Janet went separate ways fairly early on, and the creator of Fennel focussed primarily on Janet whilst the current maintainer of Fennel is responsible for much (most?) of what you see in Fennel today...So some very different design choices between the two languages, i believe.
- gsuuon 3y agoThis post inspired me to look for an ML-like language that compiles to lua and I found this useful list: https://github.com/hengestone/lua-languages https://github.com/hengestone/lua-languages
- magicalhippo 3y agoBecause it tastes amazing[1]! Oh... not the plant... [1]: https://www.foodrepublic.com/recipes/roasted-chicken-fennel/ https://www.foodrepublic.com/recipes/roasted-chicken-fennel/
- madcaptenor 3y agoIt does! I came in here expecting it was going to be about food and was disappointed.
- nultxt 3y agoGenuinely an incredibly flexible, amazing vegetable!
- rcarmo 3y agoFunny thing, I was looking at Fennel and Lua game engines... Just updated with a few: http://taoofmac.com/space/games http://taoofmac.com/space/games
- nmz 3y agoNow I like lua and think single pass is the way to go for interpreted, since you don't have the disadvantage of a slow compile time no matter how big your codebase gets, BUT its not great to write in. some things are (apparently) not possible, which means the only solution is to transpile into it, which has led to some good languages like moonscript[0], and the dynamic nature is a boon as your codebase grows, which has led to teal[1] which offers static type checking. [0]: https://moonscript.org/ https://moonscript.org/ [1]: https://github.com/teal-language/tl https://github.com/teal-language/tl
- user3939382 3y ago> is a boon A boon is a good thing. I think you meant a problem?
- agalunar 3y agoPerhaps they had in mind "bane".
- speps 3y agoDon't forget Terra as well: https://terralang.org/ https://terralang.org/
- cheeselip420 3y agoWhy does every single language landing page not have example code? I don't want to read justifications. The code should speak for itself. Show me an echo server. Show me how you open a file and read data. Show me SOMETHING. Right on the landing page. How are we still doing this? EDIT: I stand corrected - this is but a subpage. The actual landing page apparently DOES have code.
- giraffe_lady 3y agoThis isn't the landing page, which does show a code example prominently.
- arvidkahl 3y agoLinked above is a subpage. The actual homepage at https://fennel-lang.org/ https://fennel-lang.org/ has code and even an integrated place to run it.
- deleted 3y ago[deleted]
- Rochus 3y agoThere are quite many languages compiling to Lua (or LuaJIT). Fennel is just one of them. See e.g. https://github.com/hengestone/lua-languages https://github.com/hengestone/lua-languages.
- iLemming 3y agoWhat makes Fennel a bit different is that it is a Lisp inspired by Clojure. If for any reason neither of these ever interested you, then, yes, Fennel would not feel any different to you.
- Rochus 3y agoThe referenced list seems to include a language for every taste; Fennel is also there as one of ~10 Lisp variants.
- iLemming 3y agoLike I said, if one likes Clojure but has to write for a Lua-enabled platform, Fennel is the best choice today, since there's no Clojure dialect for Lua, like ClojureScript or ClojureDart. Fennel although inspired by Clojure, still a very different language. Phil Hagelberg, AKA @technomancy, is the maintainer, a well-known and highly respected Clojurista.
- the-alchemist 3y agoi was wondering why it looked so clojure-y. thanks :)
- dang 3y agoRelated. Others? Language Showcase: Fennel - https://news.ycombinator.com/item?id=32349491 https://news.ycombinator.com/item?id=32349491 - Aug 2022 (2 comments) Fennel: A Practical Lisp - https://news.ycombinator.com/item?id=31029478 https://news.ycombinator.com/item?id=31029478 - April 2022 (85 comments) Fennel – Lisp in Lua - https://news.ycombinator.com/item?id=24390904 https://news.ycombinator.com/item?id=24390904 - Sept 2020 (112 comments) Fennel – Lisp in Lua - https://news.ycombinator.com/item?id=18016168 https://news.ycombinator.com/item?id=18016168 - Sept 2018 (62 comments)
- sdfghswe 3y agoI didn't realize lua was a proper language until I learned that's what factorio uses for its mods.
- dgb23 3y agoIt's a very common language to embed in video games as a modding and configuration tool.
- SoftTalker 3y agoAnd that's the sort of thing it's meant to do. Tools have their strengths. Use them for that. Don't try to drive a nail with a screwdriver.
- whalesalad 3y agothis is a very vague statement. lua is used in a lot of environments and is very performant. you can use it inside nginx (openresty) to process requests at a pretty large scale. you can use it inside of redis. lua and javascript are somewhat interchangeable aside from the fact that js has a much larger ecosystem. sure there are situations where lua might be a bad choice but based on your remarks you make it sound like it sucks anywhere except inside a game engine.
- whalesalad 3y agoFor the clojurists this is a cool intro: https://fennel-lang.org/from-clojure https://fennel-lang.org/from-clojure
- stonemetal12 3y agoIn there it says Lua uses 'for' for looping over integer ranges and object ranges. They didn't like that so they broke it up so that for is for integer ranges and each is for object ranges. That seems strange to me. A range is a range so why have different ways to iterate over ranges based on what type of range it is?
- giraffe_lady 3y agoI mean it is lua that has two different ways to loop, with different syntax and semantics, but calls them both "for." "Numeric for" and "generic for" are the official names, with separate pages in the docs. Having different names for them seems like a reasonable and not that surprising choice.
- xigoi 3y agoRanges are not a first-class object in Lua, the range-based for loop is basically a hardcoded special case.
- sbjs 3y ago> Finally Fennel includes a macro system so that you can easily extend the language to include new syntactic forms. This feature is intentionally listed last because while lisp programmers have historically made a big deal about how powerful it is, it is relatively rare to encounter situations where such a powerful construct is justified. In other words, there are serious drawbacks to using macros that are usually outweigh any benefits they might give you.
- freilanzer 3y agoFalse, like with any feature there are use cases where macros make sense.
- reilly3000 3y agoRefreshing pragmatism re: macros >This feature is intentionally listed last because while lisp programmers have historically made a big deal about how powerful it is, it is relatively rare to encounter situations where such a powerful construct is justified.
- kazinator 3y agoYou can hardly write anything in any mainstream Lisp without using macros.
- ShadowBanThis01 3y agoBecause it's delicious.
- xwowsersx 3y agoSo I don't think I have a strong stance on the merits or drawbacks of whitespace-significant languages versus those that use parentheses (or any other syntax choices). But, I'm curious if there are any compelling arguments that objectively demonstrate why one approach might be superior to the other or if there are at least some persuasive reasons to favor one over the other. Genuinely curious!
- aidenn0 3y agoI think (and am not alone) that indentation based languages are easier for beginners to learn. The fact that indentation (whether significant to syntax or not)helps readability is something I hope I need not demonstrate since indenting is near universal in languages that use explicit delimiters. So beginners learning a language with delimiters need to learn both delimiters and indentation, and then learn that while the latter helps them more, it's actually just the former that is required. For beginners, mental load is death by a thousand cuts, so it may make more of a difference then an experienced programmer thinks. [Edit] My first reaction was just the benefits for beginners of indentation e syntax. I personally have a subjective feeling of advantages for non beginners to delimiter based syntax (I use common lisp regularly), but I have fairly low confidence in that, while I'm pretty sure of the advantages to beginners for indentation.
- xwowsersx 3y agoThat does make some sense. It's so hard to go back to the beginner's mind (though undoubtedly valuable to try!), but I think you're right that this has to be easier for a beginner. There's just less syntax overall if there aren't parentheses or curly braces.
- lenkite 3y agoDepends on the person. I knew some newbie programmers who loved Clojure and were hum-drum with Python. Some folks like parenthesis delimiters and functional programming. It structures and separates things out clearly in their mind. And when you introduce them to editing tricks like parinfer - they fall in love. The guy whom I introduced Clojure to knows it far better than me now.
- SubiculumCode 3y agoAt some point, every noun and verb in existence will also be the name of a language, framework, or piece of software. not to detract attention from this cool project in the least.
- tionis 3y agoAlso interesting is the language the original author of fennel then went on to make (with the knowledge gained by creating fennel): https://janet-lang.org https://janet-lang.org Still has a smaller community though and less appeal in the indie game scene
- ZoomZoomZoom 3y agoWhat baffled me when I researched the various Transpiled-to-Lua languages is the fact that most of them insist on dragging their runtimes with them for some strange reason. Why would I want that? Considering the common role Lua serves, in most cases where I won't be even in a position to install anything besides the single source file I can distribute. All I want is some quality of life improvements (that includes types). Write in that, then get a single Lua file as output. Nim does that with its JS-backend beautifully. I forgot if Fennel can do that (seems that's what it means by Ahead-Of-Time compilation), but it's not typed so I passed on it. I might reconsider, as I gave up on the search last time.