0

I have an symbol that evaluates to (quote ("all")). I would like to append "tests" to the end of the list, and get (quote ("all" "tests")) but I didn't find how to :

(define make-flags ''("all"))
(append make-flags '("tests")) ; Resolves to (quote ("all") "tests")

I suppose I would have to remove the quote by evaluate the make-flags twice and re-quote it, but I didn't find how to.

Hugal31
  • 1,610
  • 1
  • 14
  • 27
  • Notice that `''("all")` evaluates to `(quote (quote ("all")))`, not to `(quote ("all"))` because of the double single-quote at the beginning. Is this what you really needed? – Óscar López Jul 03 '20 at 07:02
  • Yes, that's how it is defined. I meant "once evaluated, it resolves to `(quote ("all"))`, but I am new to guile and I might be wrong. – Hugal31 Jul 03 '20 at 07:15
  • Notice that `(quote ("all"))` is just `'("all")`, but you're writing `''("all")`. That extra quote makes all the difference! But anyway, I'm not sure what's your use case. My answer solves your original question ;) – Óscar López Jul 03 '20 at 07:17
  • @ÓscarLópez I don't really agree with your comments about quoting and evaluation here. `''("all")` does indeed evaluate to `'("all")`, just as `'x` evaluates to `x` and `'3` evaluates to `3`. We have to quote such values to talk about them, but that doesn't mean that the quote is part of their actual valuess – amalloy Jul 03 '20 at 08:45
  • @amalloy Scheme evaluates `(quote whatever)` to `whatever`. `'whatever` is short for `(quote whatever)` so `''x` will evaluate `(quote (quote x))` which becomes a stupid list `(quote x)` but that some REPLs might display as `'x`. Make no mistake. the value is a list with two symbols and there isn't anything more special about the symbol `quote` than `x`. As data they are just as uninteresting to the language. – Sylwester Jul 05 '20 at 02:16
  • @Sylwester Yes, you and I agree. But Óscar López's first comment says something different, which is what I am correcting. Perhaps Óscar López meant "expands to" or "is read as" rather than "evaluates to". – amalloy Jul 05 '20 at 03:04
  • @ÓscarLópez Surely Scheme strips off the outer quote form in evaluation? – Sylwester Jul 05 '20 at 20:52
  • My first comment should be: “expands to”. And Guile in particular strips off the outer single quote when displaying a list, which I think might confuse a new user. – Óscar López Jul 05 '20 at 21:52

2 Answers2

1

Yes, you'd need to remove the quote first. Try this:

(define make-flags ''("all"))
`'(,(append (cadr make-flags) '("tests")))
=> ''("all" "tests")

It works because make-flags is just a list of this form: (quote (quote ("all"))) and we can navigate it in the usual way with car and cdr.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • On my interpeter, it shows `("all" "tests")`, while I would like `(quote ("all tests"))`. Is there a way to re-quote it, if possible after the evaluation of the append? – Hugal31 Jul 03 '20 at 07:22
  • I think you're misinterpreting the way your interpreter shows the result. `("all" "tests")` is just the way Guile displays `(quote ("all" "tests"))`. So the quote _is_ already there, it's just not shown. That would explain everything ;) – Óscar López Jul 03 '20 at 07:25
  • 1
    Anyway: if you really, really want that extra quote there, do this (notice the back quote at the beginning!): `'(,(append (cadr make-flags) '("tests"))) – Óscar López Jul 03 '20 at 07:27
  • "`("all" "tests")` is just the way Guile displays `(quote ("all" "tests"))`" Yes, but when I type `make-flags`, I get `(quote ("all"))`, so there is a second quote on the original value. But thanks for the last snippet. – Hugal31 Jul 03 '20 at 08:02
1

The second you evaluate ''("all") you get the list (quote ("all")) and it is not a quoted list at all. This is a list of to elements, the symbol quote and the list ("all"). If you want to add an element to the second element you do it by recreating the outer list and replacing the second with the new list with the added element:

(define (add-second-element ele lst)
  `(,(car lst) (,@(cadr lst) ,ele) ,@(cddr lst)))
    
(add-second-element 'goofy '((donald dolly) (mickey) (chip dale)))
; ==> (donald (mickey goofy) (chip dale))

(add-second-element "tests" ''("all"))
; ==> (quote ("all" "tests")) 

If you're not too familiar with quasiquote it's possible to do it without since quasiquote is just fancy syntax sugar for cons and append:

(define (add-second-element-2 ele lst)
  (cons (car lst) (cons (append (cadr lst) (list ele)) (cddr lst))))

(add-second-element-2 'goofy '((donald dolly) (mickey) (chip dale)))
; ==> (donald (mickey goofy) (chip dale))

Of course if the first element is always quote and there are only two elements these can easily be simplified in both versions.

Sylwester
  • 47,942
  • 4
  • 47
  • 79