Live data from Hacker News

Why Fennel?

fennel-lang.org

161–170 of 174 posts

Re: Why Fennel?

#161
post #113

Earlier quoted context omitted.

Are n4ture and torginus the same person? Why the exact repeat of the earlier post under a different name or some bots at play here?

It's not an exact repeat.

Stop karma whoring!!

If it is not suspicious then why has the comment been deleted, causing this comment to rise to the top level?

Re: Why Fennel?

#162

Earlier quoted context omitted.

I just don't understand the fixation with REPL. How do you use it? It sounds like you write code as black box then run it in REPL to see what it does because you don't understand it by yourself.

> I just don't understand the fixation with REPL Perhaps because maybe you just haven't used one? I'm not talking about "a REPL" in langs like Python, where you typically have to type stuff into it. Lisp REPLs allow evaluating code directly in the source buffer, by sending it into the REPL. That REPL can be remote. Like seriously remote - NASA once did it on a spacecraft 150 million miles away from Earth. We run ours…

You check assumptions about dynamic types this way? To see what the function even returns in the first place. Browser console has a similar function: you type a function invocation, run it, then the returned value is presented as a tree for inspection.

Re: Why Fennel?

#163

Earlier quoted context omitted.

> I just don't understand the fixation with REPL Perhaps because maybe you just haven't used one? I'm not talking about "a REPL" in langs like Python, where you typically have to type stuff into it. Lisp REPLs allow evaluating code directly in the source buffer, by sending it into the REPL. That REPL can be remote. Like seriously remote - NASA once did it on a spacecraft 150 million miles away from Earth. We run ours…

You check assumptions about dynamic types this way? To see what the function even returns in the first place. Browser console has a similar function: you type a function invocation, run it, then the returned value is presented as a tree for inspection.

You can check any assumptions about the code. But it's not exactly like using browser's dev tools console. First — you don't have to type things "somewhere else" — you're doing it right where you're writing code. And it can be a file or a scratch buffer — you don't even have to save those experimental bits. Second — because you have things neatly wrapped into symbolic expressions (those pesky parens that non-lispers find so confusing), you don't need any ceremony for setting up the stage.

take this Javascript example:

    function addFive(x) { return x + 5; }
    
or

    const addFive = (x) => x + 5;
And its counterpart in Clojurescript:

    (defn add-five [x] (+ x 5))
In javascript REPL you can eval the entire thing, but try doing it piecemeal - it makes little sense, i.e., what is (x) or => from js perspective, semantically? While Clojure variant already is a list - a native data-structure, the argument is just a vector - another native thing, etc.

So that infamous code-is-data & data-is-code mantra may not seem like a big deal in a trivial example like this, in practice, it's very nice, it allows you to do things otherwise difficult to achieve, watch this video https://www.youtube.com/watch?v=nEt06LLQaBY and give it a thought, how does one build something like that and how using a Lispy language helps there, while using more traditional PL would make things much more difficult.

Re: Why Fennel?

#164
post #99

Earlier quoted context omitted.

Sure. Here's a comment with more of an explanation: https://news.ycombinator.com/item?id=36158974

I feel like I must be missing something, because I don’t understand why representing data in an s-expression is better than representing it as nested arrays (lists of lists) and hashtables/dictionaries. I also don’t see why representing data in a language’s data structure is inherently better than representing it in a language-agnostic format like JSON, and having libraries to parse and convert data from that format…

> I don’t understand why representing data in an s-expression is better than representing it as nested arrays (lists of lists) and hashtables/dictionaries.

An s-expression is a list. An s-expression like (list (list 1 2) (list 3 4) (list 5 6)) is a list of lists. An s-expression like (hash "a" 1 "b" 2) is as hash table/dictionary.

> I also don’t see why representing data in a language’s data structure is inherently better than representing it in a language-agnostic format like JSON

You don't see why having a language data structure like Date is better than having a date-string stored in a JSON value that you need to provide parsing and other functions for? If you have a language data structure like Date, you can add days to a date, extract the month, convert it to a DateTime, etc. If you just have a JSON value, you either need to provide those functions or convert your JSON value to the Date language data structure. It seems like you see the value in using the language's data structure because you then say:

> having libraries to parse and convert data from that format into a language data structure

Also, JSON is just as "language agnostic" as s-expressions. JSON happens to be a first class component of JavaScript, as s-expressions are a first class component of Lisp; if libraries exist to help you deal with JSON in other languages, so, too, can libraries exist to help you deal with s-expressions.

> I’m struggling to understand what the tangible benefits are.

I think you understand the tangible benefits of JSON? It is a human readable/writable data serialization format. It is integrated in JavaScript in such a way that you can easily serialize, parse, and extract data from it without reaching for a library. S-expressions within Lisp do that, but they don't limit you to strings, floats, arrays, and unsorted maps. You don't need to write conversion functions or use them from a library because reading and writing s-expressions are core parts of Lisp.

Re: Why Fennel?

#165
post #164

Earlier quoted context omitted.

I feel like I must be missing something, because I don’t understand why representing data in an s-expression is better than representing it as nested arrays (lists of lists) and hashtables/dictionaries. I also don’t see why representing data in a language’s data structure is inherently better than representing it in a language-agnostic format like JSON, and having libraries to parse and convert data from that format…

> I don’t understand why representing data in an s-expression is better than representing it as nested arrays (lists of lists) and hashtables/dictionaries. An s-expression is a list. An s-expression like (list (list 1 2) (list 3 4) (list 5 6)) is a list of lists. An s-expression like (hash "a" 1 "b" 2) is as hash table/dictionary. > I also don’t see why representing data in a language’s data structure is inherently b…

I appreciate your time and explanation. I'm really trying to understand the POV here, and I feel like we're veering away from my original confusion, which was around "Try defining data in C. Try extracting data from that data you've defined in C". I'm assuming your statement would be meant to apply to other common languages without s-expressions, but maybe I've misunderstood.

I don't get why Lisp's s-expressions are much better than using arrays/tables in another language, such that they are a justification for using the language. Are they only significantly superior over a language with only arrays, like C? What's something that is made significantly easier by an s-expression than by arrays/tables?

To make s-expressions language-agnostic, wouldn't you need libraries in the languages to convert between the s-expression as it exists in some specification, and the language's native data structures? This doesn't sound all that different from JSON at this point, or a much more complex specification that defines the representation of all kinds of types, like dates.

Re: Why Fennel?

#166
post #164

Earlier quoted context omitted.

> I don’t understand why representing data in an s-expression is better than representing it as nested arrays (lists of lists) and hashtables/dictionaries. An s-expression is a list. An s-expression like (list (list 1 2) (list 3 4) (list 5 6)) is a list of lists. An s-expression like (hash "a" 1 "b" 2) is as hash table/dictionary. > I also don’t see why representing data in a language’s data structure is inherently b…

I appreciate your time and explanation. I'm really trying to understand the POV here, and I feel like we're veering away from my original confusion, which was around "Try defining data in C. Try extracting data from that data you've defined in C". I'm assuming your statement would be meant to apply to other common languages without s-expressions, but maybe I've misunderstood. I don't get why Lisp's s-expressions are…

> I'm assuming your statement would be meant to apply to other common languages without s-expressions, but maybe I've misunderstood.

It was meant for C specifically. Take a JSON document. Define it in C. Here's what I see on a random cJSON GitHub project:

https://github.com/DaveGamble/cJSON/blob/master/README.md#ex...

Now do that in JavaScript:

    const jsonDoc = { "name": "Awesome 4K" ... }

Now make the equivalent jsonDoc in Lisp with s-expressions:

    (define json-doc
      (hash "name" "Awesome 4K"
            "resolutions" (list (hash "width" 1280
                                      "height" 720)
                                (hash "width" 1920
                                      "height" 1080)
                                (hash "width" 3840
                                      "height" 2160))))

The C approach is the approach you'd similarly take in many languages where you create the HashMap, then create the Array, then populate them. Of course, you could "cheat" in many languages by first making a string and then calling the JSON library's `parse` on the string. But, this is different than JavaScript where you can directly create the JSON document. In Lisp, you are always writing s-expressions, both for data and code.

> What's something that is made significantly easier by an s-expression than by arrays/tables?

An s-expression is a form of syntax. Even though it is a "list", the s-expression (list 1 2 3) is an actual list. It's not like you're taking the idea of arrays and tables and replacing it with a list. It's like you're taking the idea:

    // Create a List in Java
    var l = new ArrayList();
    l.add(1);
    l.add(2);
    l.add(3);

    // Print the List in Java
    System.out.println(l);
    // Prints [1, 2, 3];

    // Can we construct a List from the String "[1, 2, 3]"? Is there a fromString() or similar for a Java Object?
And replacing it with the idea:

    // Create a List in Lisp
    (define l (list 1 2 3))

    // Print the List in Lisp
    (println l)
    // Prints (list 1 2 3)

    // Can we construct a List from the String "(list 1 2 3)"?
    (eval (read "(list 1 2 3)"))
What about dates? What if we want rationals? What if we want to use a binary-search-tree-map instead of a hash?

    // Create a Date in JavaScript
    const date = new Date()

    // Print the Date in JavaScript
    console.log(date);
    // Prints Wed Apr 16 2025 00:00:00 GMT ...

    // Can I JSON.parse that string and receive a date?
Lisp:

    // Create a Date in Lisp
    (define d (today))

    // Print the Date in Lisp
    (println d)
    // Prints (date 2025 4 16)

    // Construct a Date from the String "(date 2025 4 16)"
    (eval (read "(date 2025 4 16)"))
The Lisp examples are simplified, but that is the idea.

> To make s-expressions language-agnostic, wouldn't you need libraries in the languages to convert between the s-expression as it exists in some specification, and the language's native data structures?

Yes.

> This doesn't sound all that different from JSON at this point, or a much more complex specification that defines the representation of all kinds of types, like dates.

Correct. It would just be like JSON and whatever bits are standardized are what would be handled.

Re: Why Fennel?

#167
post #99

Earlier quoted context omitted.

Sure. Here's a comment with more of an explanation: https://news.ycombinator.com/item?id=36158974

I feel like I must be missing something, because I don’t understand why representing data in an s-expression is better than representing it as nested arrays (lists of lists) and hashtables/dictionaries. I also don’t see why representing data in a language’s data structure is inherently better than representing it in a language-agnostic format like JSON, and having libraries to parse and convert data from that format…

Hash tables or dictionaries can be S-expressions.

Some Lisp dialects do not have printed-representations for these; that is a bug, and needs no further discussion.

Common Lisp and Scheme have vectors: they are notated as #(...). That is an S-expression.

CLISP has a #A(...) notation for multidimensional arrays, which it can print and read:

  [8]> (make-array '(2 2) :initial-element 0)
  #2A((0 0) (0 0))
There is a little bit of a restriction in that backquote doesn't support multi-dimensional arrays:

  [2]> (let ((x 42)) `#2A((,x 0) (0 ,x)))
  *** - READ: unquotes may not occur in arrays
But this does work for vectors (as required by ANSI CL, I think):

  [11]> (let ((x 42)) `#(0 ,x 0))
  #(0 42 0)
You might think that #(0 42 0) is just some list variation, but in fact it is a bona-fide vector object, with fast numeric indexing, and without the structural flexibility of lists. Vectors are typically implemented as flat arrays in memory. (Though they could use something else, particularly if large, like radix trees.)

Hash literals look like this in TXR Lisp:

  1> #H(() (a 1) (b 2) (c 3))
  #H(() (a 1) (c 3) (b 2))
You can see the order of the keys changed when it was echoed back. The first element in the #H syntax, (), gives properties. It's empty for the most general form of hash, which uses equal comparison, and doesn't have weak keys or values.

Binary search trees are likewise printable. The #T notation gives a tree (concealing the nodes). The #N notation for individual tree nodes:

  1> (tree)
  #T(())
  2> (tree-insert *1 1)  ; *1 means value from repl line 1
  #N(1 nil nil)
  3> (tree-insert *1 3)
  #N(3 nil nil)
  4> (tree-insert *1 7)
  #N(7 nil nil)
  5> (tree-insert *1 4)
  #N(4 nil nil)
  6> (tree-insert *1 2)
  #N(2 nil nil)
  7> (tree-insert *1 8)
  #N(8 nil nil)
  8> (tree-insert *1 0)
  #N(0 nil nil)
  9> *1
  #T(() 0 1 2 3 4 7 8)
  10> (tree-root *1)
  #N(3 #N(1 #N(0 nil nil) #N(2 nil nil)) #N(7 #N(4 nil nil) #N(8 nil nil)))
The #T notation is readable. It gives the values in order, but they don't have to be specified in order when you write a literal:

  11> #T(() 3 2 1)
  #T(() 1 2 3)
If we ask for the tree root, we see the actual nodes, and how they are linked together:

  12> (tree-root *11)
  #N(2 #N(1 nil nil) #N(3 nil nil))
All these notations are something we can casually use as data in a file or network stream between TXR Lisp programs, or anything else that cares to read and write then notation.

The printed notation of any object in a Lisp is a S-expression. S-expression syntax usually strives for print-read consistency: when an object's printed notation is read by the machine, a similar object is recovere. (In some cases, the original object itself, as with interned symbols).

Re: Why Fennel?

#168

Earlier quoted context omitted.

Hey... could you write about one or two of the worst offenses? I consider myself an emacs/elisp power user, yet somehow (M)ELPA seems pretty doinked out-of-the-box on a stock Debian nox-emacs install. I just thought it was me.

My apologies, but I no longer remember. I only remember my huge annoyance that almost anything I did, even successful, led to some warnings or unnecessary notifications in the command bar. Always some noise there. Not to mention the occasional actual failure in a plugin leading to huge stacktraces and leaving me with a partially working editor that kind of still works but not quite. My brain mercifully deleted all de…

Fair enough. I envy your brain's ability to excise editor-induced trauma. There are so many things about modern EMACS I don't like, but for me I think it's inertia that keeps me in a co-dependent relationship with it. (and... I have to admit... it does do many things well.)

Re: Why Fennel?

#169

Earlier quoted context omitted.

My apologies, but I no longer remember. I only remember my huge annoyance that almost anything I did, even successful, led to some warnings or unnecessary notifications in the command bar. Always some noise there. Not to mention the occasional actual failure in a plugin leading to huge stacktraces and leaving me with a partially working editor that kind of still works but not quite. My brain mercifully deleted all de…

Fair enough. I envy your brain's ability to excise editor-induced trauma. There are so many things about modern EMACS I don't like, but for me I think it's inertia that keeps me in a co-dependent relationship with it. (and... I have to admit... it does do many things well.)

I was in a co-dependent relationship as well. I have to admit it was extremely uncomfortable to "part ways".

> * I envy your brain's ability to excise editor-induced trauma.*

That's a really funny way of putting it, thanks. I am simply one of the people who never truly settles and if something irks me for long enough, I ultimately cut the toxic element. And yeah it's often painful.

But that also gave me my amazing wife. If I stuck with my toxic ex I would be absolutely nowhere in life right now.

Re: Why Fennel?

#170

Earlier quoted context omitted.

Nope. Neovim. And even there some of the "distros" got on my nerves. I guess at one point I'll just learn Neovim's API and make my own blend like everyone else. NOT looking forward to it. But I suppose there's no other way. I still view Neovim as a huge improvement over Emacs though.

> I still view Neovim as a huge improvement Neovim unlike Emacs is an editor. Emacs is not a mere code editor, not an IDE, text-processor, or web-browser. Emacs first and foremost is a Lisp REPL, with a built-in text-editor. Without deeply understanding that aspect one can never truly appreciate the incredible power it grants you. Do you use your editor to read and annotate pdfs? Or watch videos? Or manage the librar…

Care to share your .emacs? :)
Post reply on HN