Live data from Hacker News

GNU Guile 2.2.0

gnu.org

41–50 of 149 posts

Re: GNU Guile 2.2.0

#41

Why are those brackets there in the syntax? What's the need? It looks hard to read when the programs are bigger. Is there any super advantage to it?

In lisp/scheme, you write the abstract syntax tree, skipping the parse step entirely.

> skipping the parse step entirely.

Not strictly true... there is still parsing involved in reading Lisp data structures from a character stream. (It's just much less involved than in traditional infix languages.)

The way to think of it is this: 1) Lisp has a much more comprehensive (and read/write) syntax for its core data structures. 2) Lisp, the language, is defined in terms of those data structures rather than in terms of character sequences and grammar productions.

Re: GNU Guile 2.2.0

#42
post #21

Why are those brackets there in the syntax? What's the need? It looks hard to read when the programs are bigger. Is there any super advantage to it?

The super advantage of Lisp (including Scheme): Its format for defining data is the same as for writing code, making macros a natural part of the syntax: You can change your source code just like you’d change any other list (or rather tree) data type. However all this can be represented fully without parentheses — and this is possible with Guile using a reader extension without losing any of its power. This is realiz…

> The super advantage of Lisp (including Scheme): Its format for defining data is the same as for writing code, making macros a natural part of the syntax: You can change your source code just like you’d change any other list (or rather tree) data type.

I've heard this repeatedly over the years, but the explanation unfortunately always stops right there. Could you please give an example of why you'd want to change your source code programatically? It's always assumed that the reader implicitly knows why this is a good and important thing. Perhaps a practical example showing

(A) how this would work,

(B) what the benefit is, and

(C) how the added work in reasoning is worth that benefit.

Note: I personally like the parentheses, as they group everything together so simply.

Re: GNU Guile 2.2.0

#43
post #21

Earlier quoted context omitted.

The super advantage of Lisp (including Scheme): Its format for defining data is the same as for writing code, making macros a natural part of the syntax: You can change your source code just like you’d change any other list (or rather tree) data type. However all this can be represented fully without parentheses — and this is possible with Guile using a reader extension without losing any of its power. This is realiz…

> The super advantage of Lisp (including Scheme): Its format for defining data is the same as for writing code, making macros a natural part of the syntax: You can change your source code just like you’d change any other list (or rather tree) data type. I've heard this repeatedly over the years, but the explanation unfortunately always stops right there. Could you please give an example of why you'd want to change yo…

>Could you please give an example of why you'd want to change your source code programatically?

To create new syntax and be your own language designer. This is what macro systems allow for. Here's a very contrived and simple example. Guile comes with no equivalent of the `++` operator that we know from C, C++, etc. So in the event that we have some imperative code that is mutating a counter, we'd have to write something like this:

    (define counter 0)
    ;; do some stuff...
    (set! counter (+ counter 1))
Quite a lot more typing! It would be especially annoying if we had many such counters. Normally, when we want to factorize code, we'd write a function, but there's a problem: We can't write a function that mutates any given variable. So, this wouldn't work:

    (define (++ n) (set! n (+ n 1)))
    (define counter 0)
    (++ counter)
This is just mutating a local variable `n`, nothing happens to the variable `counter`, it's still 0. So what do we do? Instead of a function abstraction, we'll use a syntactic abstraction instead. Here is a macro that does what we want:

    (define-syntax-rule (++ var) (set! var (+ var 1)))
    (define counter-a 0)
    (define counter-b 0)
    (++ counter-a)
    (++ counter-b)
    (++ counter-a)
Now `counter-a` is 2 and `counter-b` is 1. The `++` macro is a program that writes programs. It takes `(++ counter-a)` and expands it into the code `(set! counter-a (+ counter-a 1))`.

The reason these syntactic abstractions are so easy to make is because of the homoiconic Lisp syntax. I hope this has made sense and is helpful. Moving on from this simple example, we can create entirely new languages that are embedded in Scheme if we wanted to, adding things that are too specific to a problem domain to ever be in the standard language's syntax but very useful for the problem we are trying to solve.

Re: GNU Guile 2.2.0

#44
post #32

Earlier quoted context omitted.

What's left to be done?

I'm not involved in Emacs/Guile/GuileEmacs development. I just searched emacs-devel / EmacsWiki before writing that comment. Having said that it seems to be in a POC state, but is very slow and needs optimization. These two wiki pages provide a decent overview: https://www.emacswiki.org/emacs/GuileEmacs & https://www.emacswiki.org/emacs/GuileEmacsTodo This "Preview: portable dumper," thread from November 2016 and spi…

> Thanks to the work of Robin Templeton, Guile's Elisp implementation is now fully Emacs-compatible, implementing all of Elisp's features and quirks in the same way as the editor we know and love.

Robin Templeton also seems to be the one which finished off the elisp compatibility on Guile here so it's probably because he saw that as important to get first.

Re: GNU Guile 2.2.0

#45
post #21

Earlier quoted context omitted.

The super advantage of Lisp (including Scheme): Its format for defining data is the same as for writing code, making macros a natural part of the syntax: You can change your source code just like you’d change any other list (or rather tree) data type. However all this can be represented fully without parentheses — and this is possible with Guile using a reader extension without losing any of its power. This is realiz…

> The super advantage of Lisp (including Scheme): Its format for defining data is the same as for writing code, making macros a natural part of the syntax: You can change your source code just like you’d change any other list (or rather tree) data type. I've heard this repeatedly over the years, but the explanation unfortunately always stops right there. Could you please give an example of why you'd want to change yo…

Could you please give an example of why you'd want to change your source code programatically?

This is my favorite example.

http://www.gigamonkeys.com/book/macros-standard-control-cons...

[Common Lisp's] DOLIST is similar to Perl's foreach or Python's for. Java added a similar kind of loop construct with the "enhanced" for loop in Java 1.5, as part of JSR-201.

Notice what a difference macros make. A Lisp programmer who notices a common pattern in their code can write a macro to give themselves a source-level abstraction of that pattern.

A Java programmer who notices the same pattern has to convince Sun that this particular abstraction is worth adding to the language. Then Sun has to publish a JSR and convene an industry-wide "expert group" to hash everything out. That process--according to Sun--takes an average of 18 months. After that, the compiler writers all have to go upgrade their compilers to support the new feature. And even once the Java programmer's favorite compiler supports the new version of Java, they probably still can't use the new feature until they're allowed to break source compatibility with older versions of Java.

So an annoyance that Common Lisp programmers can resolve for themselves within five minutes plagues Java programmers for years.

Re: GNU Guile 2.2.0

#46
post #8

Why are those brackets there in the syntax? What's the need? It looks hard to read when the programs are bigger. Is there any super advantage to it?

It's a LISP dialect. Brackets are essential to tell the difference between arguments and function calls... take for example in C: foo(bar(1)) would in lisp be (foo (bar 1)). If it were to just be "foo bar 1", you couldn't tell the difference between (C style again for clarity): foo(bar(1)) and foo(bar, 1). Some newer functional languages have a composition operator which allows you to write this without the brackets,…

> If it were to just be "foo bar 1", you couldn't tell the difference between (C style again for clarity): foo(bar(1)) and foo(bar, 1).

Or `foo(bar)(1)`.

Re: GNU Guile 2.2.0

#47
post #15

For me this is the most exciting part: Complete Emacs-compatible Elisp implementation Thanks to the work of Robin Templeton, Guile's Elisp implementation is now fully Emacs-compatible, implementing all of Elisp's features and quirks in the same way as the editor we know and love. This means we can finally have a proper GuileEmacs!

The question is more of the strings are fast enough yet. You could have GuileEmacs for a long time, but they weren't fast enough.

Re: GNU Guile 2.2.0

#48
post #20

For those excited about the "Guile's Elisp implementation" in this release. The last major Guile release was 6 years ago, and much of this GuileEmacs work is still highly WIP and from my searching on emacs-devel seems to have stalled in 2015 for lack of volunteers. Just because Guile implements Elisp the language doesn't mean there isn't a ton of work to be done on Emacs itself to swap out its native VM for Guile, an…

What's left to be done?

One big item is that that Emacs' internal string/buffer representation supports things like loading weirdly (or even erroneously) encoded data, and saving this unchanged; this is sometimes quite useful.

Guile's strings (gnulib's) do not support that, and adding the support is quite a bit of works for all the corner-cases that emacs supports.

Now, emacs and guile do not necessarily have to use the same underlying string/buffer implementation, but it would definitely be a big plus, and I wouldn't be surprised the emacs maintainers would require it.

Re: GNU Guile 2.2.0

#49
post #47
post #15

For me this is the most exciting part: Complete Emacs-compatible Elisp implementation Thanks to the work of Robin Templeton, Guile's Elisp implementation is now fully Emacs-compatible, implementing all of Elisp's features and quirks in the same way as the editor we know and love. This means we can finally have a proper GuileEmacs!

The question is more of the strings are fast enough yet. You could have GuileEmacs for a long time, but they weren't fast enough.

No, we couldn't have had GuileEmacs for a long time since the compatibility layer with Elisp wasn't complete - that meant that not all Existing Emacs packages could be used as is with a GuileEmacs. This release specifically addresses that and I am sure that now there will be serious effort to bring about a "stable" GuileEmacs release.

Re: GNU Guile 2.2.0

#50
post #21

Earlier quoted context omitted.

The super advantage of Lisp (including Scheme): Its format for defining data is the same as for writing code, making macros a natural part of the syntax: You can change your source code just like you’d change any other list (or rather tree) data type. However all this can be represented fully without parentheses — and this is possible with Guile using a reader extension without losing any of its power. This is realiz…

> The super advantage of Lisp (including Scheme): Its format for defining data is the same as for writing code, making macros a natural part of the syntax: You can change your source code just like you’d change any other list (or rather tree) data type. I've heard this repeatedly over the years, but the explanation unfortunately always stops right there. Could you please give an example of why you'd want to change yo…

The syntax is mininal, here it is: (functionOrMacroOrSpecialForm arg1 arg2 ...)

That's the whole syntax. So now you know how to program in LISP.

There's no statements in lisp, only the above expression repeated, which you can nest one in another, or sequence them one after another. They're called S-expressions.

For me, that simplicity is the first advantage. It's just very consistent and quick to learn. It also allows to embed everything together, like assign a value in an if condition.

The second big advantage, is that this syntax is very easily parsed into a list and can be easily changed programatically. Lisp lets you do that by defining macros.

A) It works by defining a function which takes the parsed code as an AST, and returns a modified AST. To transform the AST you have the full power of LISP availaible and some convenient operators that make it easier.

B) There's many benefits. Conceptually, it lets you change the evaluation order of code. Normally a function evaluates its arguments from left to right and then passes the resulting values to be evaluated by the function. 99% of the time this is what you want. But what if you want to short-circuit the evaluation of the arguments when one of them evaluates to say false. This would come in handy if writing the AND function. A macro allows you to do it. In other languages, you're given special operators for this kind of thing, but they're limited and you can not add new ones.

Another practical case is aspect oriented programming. Imagine you want to print the argument to all functions and all their return values. With a macro you can do this:

(print-steps (+ (- 100 23 price) (* 12 34 56 people))).

Print steps is able to inject a print statement at multiple code points, around each arguments and around every functions. Without a macro, you would have had to re-write all this manually, and then delete it again once you're done debugging. Some languages like Java give you a complicated framework which can do this to a certain extent, but aspect-J is a pre-processor, just like macros, it's just that the Java syntax makes this really complicated to implement, so you need a framework to do most of the work, or it's not practical.

C) That's up to you to decide. You don't ever have to write a single macro, and should only use them when they are needed and make sense. Now reading code with macros is trickier, because every macro could be a custom operator you have never seen before, or an aspect that does things you're not sure about. To me, this just becomes a thing of don't write crappy unreadable code. Which is true in all languages. I'd suggest teams standardize their macros, and document them well, so new members can quickly get familiar with your team's macros. Once familiar with a set of macros though, they make you a lot more productive and do make code more concise and even easier the read sometimes.

Post reply on HN