Scheme question

The code below works fine.

(define (centered-pygments)
  (insert
    '(code
       (document
         (script-input "pygments" "default"
                       (document "%cpp; texmacs") "")))))

However, this one does not (I get compound-string-error).

(define (centered-pygments)
  (insert
    '(code
       (document
         (script-input "pygments" "default"
                       (document (string-append "%cpp;" " texmacs")) "")))))

I’m trying to write do the following:

(kbd-commands
  ("cp" "" (centered-pygments "cpp")))

(define (centered-pygments language)
  (insert
    '(code
       (document
         (script-input "pygments" "default"
                       (document (string-append "%" language "; texmacs")) "")))))

This one just fails.

The quote before ‘code’ means that what follows will be interpreted literally, without evaluation. Therefore, a ‘string-append’ element will be inserted into TeXmacs, which it doesn’t know. Try putting a comma before ‘(string-append …)’. This should make Scheme evaluate it before inserting.

1 Like

As @jeroen says you are not using properly the quotation mechanism. There are two quotations notations, the one you are using '(code ...) (with apostrophe) and another one `(code ....) (with backtick), it is called “quasi quote”. This second one allow an “escape” back to evaluation mode (unquoting) with , (comma), so your code should read instead

(define (centered-pygments language)
  (insert
    `(code
       (document
         (script-input "pygments" "default"
                       (document ,(string-append "%" language "; texmacs"))))))) 

note the backtick and the comma in the right places. The quasi quoting mechanism and be freely mixed with the quoting and also iterated. Note there is another operator ,@ (comma-at) which evaluates an expression that should return a list and then splice the list in the outer expression., example:

`(1 2 3 ,@(list 4 5 6)) == '(1 2 3 4 5 6)

compare with

`(1 2 3 ,(list 4 5 6)) == '(1 2 3 (4 5 6))

Note also that TeXmacs has the concat macro so instead of string-append I think you can write more simply

(define (centered-pygments language)
  (insert
    `(code
       (document
         (script-input "pygments" "default"
                       (document (concat "%" ,language "; texmacs"))))))) 

and probably get rid of the document tag altogether, but I haven’t tested it.

1 Like

@jeroen, thanks for the tip. If I may ask, are you the author of the pygment plugin? I use it extensively.

1 Like

While the above code snippets do indeed work, I am no longer able to execute the script. For example, after inserting the script and pressing Shift+Return, the script would run. Now, pressing Shift+Return doesn’t do anything.

Note that I made a mistake in copying your snippet, I think the right code is

(define (centered-pygments language)
  (insert
    `(code
       (document
         (script-input "pygments" "default"
                       (document ,(string-append "%" language "; texmacs")) 
                       "")))))

I forgot the last "" argument for script-input.

Thanks. I didn’t notice that myself.

I find scheme really hard to work it. It still hasn’t clicked yet. I easily get lost in the myriad of parenthesis, even though I have syntax highlighting on.

from https://xkcd.com/297/

Maybe it could be a useful exercise to imagine how a function like centered-pygments could be written in another language (e.g. Python or Javascript). Note that non of these languages have quotation (if I’m not wrong), even if JSON objects are relatively easy to use. I guess that it would require more code for the same result.

I’m not arguing that lisp-based languages are not ideal from the computer science point of view; it’s just that they are just harder to read. With other languages, you just allow your eyes to pass through the code and you immediately know what it is doing. With lisp, even trivial things like if statements require mental parsing. I really believe if TeXmacs had adopted a more widely-used programming language, it would have had a much larger base. Take neovim for instance. As soon as they moved from vimscript to lua, the ecosystem has flourished. Suddenly, everyone is able to contribute. I use neovim myself and have written a couple of plugins; something I wouldn’t have done in vimscript. Scheme could very likely be the best programming language ever written, but there’s a reason why imperative languages like C/C++, Java, etc., took off; the programming style they offer resonate more with the wider audience.

Maybe. I do not know what foster wide adoption. (Typsts has its own scripting language and use Rust and seems to be quite popular) Clojure and Emacslisp are quite popular, I would be happy if we have 1% of their contributors. I could live with Javascript (or Lua) but they do not have macros (and is not easy to have macros without an homogeneous language syntax). Also I have not implied that Lisps are “better”. But I feel more satisfied writing few lines of Scheme than a page of python.

But TeXmacs is written in Scheme and no changes are in view in the short term. So I guess my remark was more about that instead of considering writing Scheme a burden, you could take it as an exercise, like those people do going in the gym. Paul Graham wrote a famous essay on the benefits of Scheme programming : http://www.paulgraham.com/avg.html and I recently discovered this beautiful book https://www.cambridge.org/core/books/lisp-in-small-pieces/66FD2BE3EDDDC68CA87D652C82CF849E which is worth every page (and I cannot say the same of other books I bought on Javascript or Python or C++ for what matters).

I find also interesting that one of the developer of Julia wrote this: https://github.com/JeffBezanson/femtolisp/blob/master/README.md

I hope that these opinions from a bunch of different people could make you a bit more patient with the chaos of parentheses. To me it helps to use proper indentation to see the structure. I would have also liked that TeXmacs use the same structure highlighting for Scheme as it does for documents, i.e. that one could “see” where he is in a Scheme expression wrt. to the hierarchy of nested expressions. This should not be difficult to do.

I’ll have a look at some your references. Thanks. It’s funny that I am convinced that no one really likes to use lisp, but they pretend they do because it is different, and that puts them in some rarefied group.

Yes, I wrote that plugin. Glad to hear it has been useful!

I haven’t really used it myself yet, it was a kind of exercise in plug-in writing. It could be improved, maybe someday I’ll get round to that :blush:

1 Like

Well people use schemes, they are just not very vocal about it. Chez Scheme is maintained by CISCO, Clojure is a popular lisp implementation, Common Lisp seems to have adepts still now, people even use it for engineering stuff (https://www.youtube.com/watch?v=8X69_42Mj-g), the parser of the Julia language is written in femtolisp, Racket has many adepts and is continuously developed, Haskell with macros looks very much like lisp, i.e. Hackett, Emacs is written in Lisp, TeXmacs too. The hacker news website is written in Arc … A rising Linux distribution Guix is completely developed in Guile…

I also, like @mgubi, think that indentation helps a lot in seeing the structure.

I think that in order to write Scheme, one is much better off by writing it with editor support; that is, the editor needs to take care of parentheses and indentation for you.

I am using emacs, which detects that one is editing a Scheme file and indents accordingly, with paredit ( paredit — parenthetical editing in Emacs) that takes care of the parentheses (one can even move subexpressions in-out of a parenthesis with easy keyboard shortcuts). I made a short web search and there may be something for Sublime Text too. I think it is worth checking whether Scheme editing help exists for one’s favourite editor.

Here is a guide for Scheme indentation:
scheme-style (schemewiki.org)

I went quickly through it and it seems sensible (or, it seems like the rules I got used to).

Thanks but the recommendation, but I don’t use sublime. I use neovim.

Then Scheme support for neovim. I would start with this:
paredit.vim - Paredit Mode: Structured Editing of Lisp S-expressions : vim online

Then https://stackoverflow.com/a/31999765 and possibly crash.net.nz

A post was split to a new topic: Pygments plugin

As for parenthesis. If you work in TeXmacs you can activate the preferences related to bracket highlight/selection and matching to make easier to work with Scheme files (and also Python, Fortran, C++,…)

Then you will have matching parentheses highlighted when you are near them with the cursor.

1 Like

An btw: a nice new scheme primer here:

https://spritely.institute/static/papers/scheme-primer.html

1 Like

Thanks for the link. I was reading a short tutorial on scheme the other day. Most things were straight-forward except symbols. I wanted to think of them as pointers, but I know they are not. How would you explain what symbols are to someone familiar with C/Python?