Scheme question

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?

symbols are symbols. tokens, abstract unique objects. why you think to them as pointers? they are objects. I think you make confusion with variables. symbols are used to identify variables in an environment. One could use numbers or strings to do the same thing but symbols are more convenient. C/Python do not have similar entities. I guess what is nearer would be some Python singleton class, a symbol is something which is uniquely identified by its printed form, so there can only be one symbol with a given representation, while strings a priori can be different, in the sense that “abc” and “abc” while being equal in some sense, could be just two strings allocated in different parts of memory, so represented by different pointers (in C). the symbol 'abc and the symbols 'abc are the same symbol in every sense. They are useful as keys in maps, and in particular to retrieve values in an environment. They are the “names” of certain variables, i.e. certain mutable container for other scheme objects.

Note that in scheme every expression has a value. An expression is a list made of other lists or atoms, atoms are symbols, strings, chars, numbers, booleans. Booleans, chars, integers, string are self-evaluating, meaning that the value of an expression consisting only of one of them is itself. The value of a symbol is defined from the environment (it is looked up in a table and its value is the associated object, i.e. it acts as the name of a variable). The value of a list expression is the result of calling the function which is the value of the expression corresponding to the first element with parameters which are the values of the expressions corresponding to the other elements of the list. If you want a symbol as a value, you have to avoid it to be interpreted as the location of a variable, for this we use quote, i.e. the symbol value abc is expressed with the expression 'abc. The same for lists: if you want a list then you have to quote a list expression '(a b c), in this case a list of symbols, while this: '("a" "b" "c") is a list of strings and this: (a b c) is evaluated as the function a called with parameters b and c. This is essentially all that Scheme is (apart from macros).

1 Like