1

In Racket, the following works:

(+ . [1 2]) ; => 3

{ define a + }
(a . [1 2]) ; => 3

However, i see no way to define b to be the (1 2) list so as to get (+ . b) and (a . b) to return 3. Is it possible?

Óscar López
  • 232,561
  • 37
  • 312
  • 386
Alexey
  • 3,843
  • 6
  • 30
  • 44
  • 2
    Re your most recent edit, titled "use my style for code": please don't use that "style". Use round brackets everywhere: http://mumble.net/~campbell/scheme/style.txt. Some people like to use square brackets for variable bindings, and it's well-established enough in some circles that it's okay, but making up your own bracketing scheme ensures that nobody else can read your code. – C. K. Young Mar 26 '13 at 11:54
  • 1
    @Chris, i'll think about it, but you are wrong about "ensures that nobody else can read your code": if a simple substitution of round brackets everywhere converts the code into one you consider readable, then the code itself should be considered readable, because the operation of substitution is sufficiently simple to perform mentally or even visually. Apart from that, i am not sure yet that my style is not self-contradicting somewhere, but for now it looks more readable than the standard one. – Alexey Mar 26 '13 at 12:24
  • 3
    The reason I say what I said is that experienced Lisp and Scheme programmers have learnt to "not see" the round brackets: i.e., they are effectively invisible. They're there for ease of machine parsing, not for human reading. When you introduce other bracket types into the mix, they're not so easy to ignore, because Lisp/Scheme programmers haven't been trained to ignore those. – C. K. Young Mar 26 '13 at 15:57
  • Seasoned Lisp/Scheme programmers use editors, like paredit, that handles brackets for them, so that they **never count brackets manually**. This is important. (And one day I want to write a userscript for Stack Overflow so I can get paredit functionality on the site, so I don't have to cut and paste from a real editor.) – C. K. Young Mar 26 '13 at 16:00
  • @Chris, i am just trying to benefit from the fact that different brackets in Racket can be used interchangeably. I wonder if this can be used to improve the readability of the code. This would be a separate discussion, but it bothers me that people do not seem to claim that they get to like the Lisp parenthetic syntax with time, they just say that it "fades away". "--- I do not like your husband. --- Do not worry, once you get to know him better he will fade away, look at the nice apartment he's got." – Alexey Mar 26 '13 at 16:52

2 Answers2

2

Sure, just use apply:

(define a +)
(define b '(1 2))
(apply a b)       ; => 3
(apply + b)       ; => 3
C. K. Young
  • 219,335
  • 46
  • 382
  • 435
  • 1
    I do not want to use `apply`, i wonder if there is a way to make the dotted pair notation treat equally both elements, or if not, what is the reason. If it was possible, maybe there would be no need to ever call `apply`. – Alexey Mar 26 '13 at 12:27
  • The `.` notation is processed at the reader level, before the binding for `b` even exists. There's no way for the reader to turn `(a . b)` into `(a . 1 2)` since it doesn't know `b` is `'(1 2)`. – Asumu Takikawa Mar 26 '13 at 13:21
  • @AsumuTakikawa, but it knows in `(a . [1 2])` that `a` is `+`. I do not understand why in evaluating `(a b c)`, all elements are evaluated first, but in an unquoted dotted pair, only the first element is evaluated, the second has to be given as a literal atom, or as an s-expression, of which the entries will be evaluated (i am not sure i am using the terminology correctly). – Alexey Mar 26 '13 at 14:38
  • @Alexey: You can design an evaluator to treat an improper expression as an implicit `apply`, but there are still cases where `apply` is required. For example, what if you wanted to do `(apply + (map square nums))`? You can't write that as `(+ . (map square nums))`, since the reader will read that as `(+ map square nums)`. – C. K. Young Mar 26 '13 at 15:53
  • @Alexey: As for your other question, `(a . (1 2))` is read in as `(a 1 2)` and the two forms cannot be distinguished in any way. – C. K. Young Mar 26 '13 at 15:55
  • @ChrisJester-Young, thanks for the explanation. In fact, what i was looking for, was to understand that in the syntax tree constructed at the reader level only car's are ever interpreted, so even if it is possible to parse `(a . b)`, it would be impossible to evaluate `b` later. If you add something like this to your answer, i will accept it. – Alexey Mar 26 '13 at 20:00
1

How about this ... without using apply but using eval. But seriously, using apply is a better idea in this case, there's nothing wrong with it (eval is evil though, see the documentation to understand the last part with the namespace):

(define a +)
(define b '(1 2))

; executing in the evaluation window

(eval `(+ ,@b))
=> 3
(eval `(a ,@b))
=> 3

; executing from the definitions window

(define-namespace-anchor an)
(define ns (namespace-anchor->namespace an))    
(eval `(+ ,@b) ns)
=> 3
(eval `(a ,@b) ns)
=> 3
Community
  • 1
  • 1
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • Thanks for the examples, but i would like to understand why something like `(define a +) (define b (list 1 2)) (a . b) ; => 3` is not allowed by the compiler. – Alexey Mar 26 '13 at 14:45
  • It has been explained in @AsumuTakikawa' comment: The `.` notation is processed at the reader level, what you want to do (evaluate an expression based on the value of two variables) occurs at a different time, so by definition it can't be accomplished _unless_ a procedure such as `eval` or `apply` is used to process the expression after the reading phase is over. – Óscar López Mar 26 '13 at 18:29
  • Well, i see that it would not be clear how to evaluate `(+ . (list 1 2))`, as `(+ 1 2)` or `(+ list 1 2)`. I'll think more. – Alexey Mar 26 '13 at 19:36
  • I think i've understood your example: it is the same as `(eval (quasiquote (a (unquote-splicing b))))`, right? – Alexey Mar 26 '13 at 20:05
  • @Alexey yes, it's _exactly_ the same. I'm just using a shorter syntax – Óscar López Mar 26 '13 at 21:19