Dear all,
I was fooling around with reader macros to implement some - let's say - "tuple" syntax.
Now, I am just curious about the general thinking on this.
First of all, let's note that the problem here in the conflating of the "constructor" with the "printed representation" of an item. I.e., in Matlab you say
[1, 2, 40 + 2]
ans = 1 2 42
In CL, doing the simple thing, you get
cl-prompt> [1 2 (+ 40 2)] [1 2 42]
but
cl-prompt> #(1 2 (+ 40 2)) #(1 2 (+ 40 2))
So, suppose you have your [ … ] reader macro, would you have it work "functionally" or "quoting-ly" (for want of a better word)? I am curious. Note that the Matlab-style version would not break referential transparency if you did not have mutations.
best
Marco Antoniotti
-- Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01 DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it Viale Sarca 336 I-20126 Milan (MI) ITALY
Please note that I am not checking my Spam-box anymore. Please do not forward this email without asking me first.
I see a couple potential issues. (Better terms for whether the reader macro evaluates subforms might be "evaluating" and "quoting".)
If the elements inside the syntax are permitted to be non-self-evaluating objects such as symbols or conses, then under the evaluating option one would need to write [1 'x (+ 40 2)].
Second, as I'm sure you realize, the evaluation model at read time is very different from regular evaluation in that it always happens in the read-time dynamic environment and the null lexical environment. This doesn't matter if the computations are just simple arithmetic, but it makes read-time evaluation feel messy to me, especially if someone might later use it with more-complex forms.
You might also consider inside your reader macro borrowing the syntax and meaning of the backquote comma: [ 1 x ,(+ 40 2) ]. This might make the meaning and environment more evident to experienced CL programmers (although comma forms evaluate at run time in the current lexical environment).
On Mon, Dec 3, 2012 at 5:12 AM, Marco Antoniotti < antoniotti.marco@disco.unimib.it> wrote:
Dear all,
I was fooling around with reader macros to implement some - let's say - "tuple" syntax.
Now, I am just curious about the general thinking on this.
First of all, let's note that the problem here in the conflating of the "constructor" with the "printed representation" of an item. I.e., in Matlab you say
[1, 2, 40 + 2]
ans = 1 2 42
In CL, doing the simple thing, you get
cl-prompt> [1 2 (+ 40 2)] [1 2 42]
but
cl-prompt> #(1 2 (+ 40 2)) #(1 2 (+ 40 2))
So, suppose you have your [ … ] reader macro, would you have it work "functionally" or "quoting-ly" (for want of a better word)? I am curious. Note that the Matlab-style version would not break referential transparency if you did not have mutations.
best
Marco Antoniotti
-- Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01 DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it Viale Sarca 336 I-20126 Milan (MI) ITALY
Please note that I am not checking my Spam-box anymore. Please do not forward this email without asking me first.
pro mailing list pro@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/pro
On Mon, Dec 3, 2012 at 8:12 AM, Marco Antoniotti < antoniotti.marco@disco.unimib.it> wrote:
Dear all,
I was fooling around with reader macros to implement some - let's say - "tuple" syntax.
Now, I am just curious about the general thinking on this.
First of all, let's note that the problem here in the conflating of the "constructor" with the "printed representation" of an item. I.e., in Matlab you say
[1, 2, 40 + 2]
ans = 1 2 42
In CL, doing the simple thing, you get
cl-prompt> [1 2 (+ 40 2)] [1 2 42]
but
cl-prompt> #(1 2 (+ 40 2)) #(1 2 (+ 40 2))
So, suppose you have your [ … ] reader macro, would you have it work "functionally" or "quoting-ly" (for want of a better word)? I am curious. Note that the Matlab-style version would not break referential transparency if you did not have mutations.
I struggled with this very question in Antik (grid syntax with #m). What I decided was it should mimic CL #(, i.e., not evaluate. For evaluation, I have function(s), particularly #'grid, so
ANTIK-USER> (setf *default-grid-type* 'foreign-array) FOREIGN-ARRAY ANTIK-USER> (grid 1 2 (+ 40 2)) #m(1.000000000000000d0 2.000000000000000d0 42.000000000000000d0)
(Note #'grid doesn't take as arguments any options like the grid type, just elements, but there are other functions that will.) My reasoning was mainly to be consistent with CL, but also somehow a reader macro triggering an evaluation seemed wrong; a function was the most appropriate way to do that. I can't recall right now the problem that caused me to switch (before, it did do evaluation), but it was a mess and this was the easiest way to clean it up.
Liam
best
Marco Antoniotti
-- Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01 DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it Viale Sarca 336 I-20126 Milan (MI) ITALY
Please note that I am not checking my Spam-box anymore. Please do not forward this email without asking me first.
pro mailing list pro@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/pro
On Tue, Dec 4, 2012 at 3:19 AM, Liam Healy lnp@healy.washington.dc.us wrote:
On Mon, Dec 3, 2012 at 8:12 AM, Marco Antoniotti antoniotti.marco@disco.unimib.it wrote:
Dear all,
I was fooling around with reader macros to implement some - let's say - "tuple" syntax.
Now, I am just curious about the general thinking on this.
First of all, let's note that the problem here in the conflating of the "constructor" with the "printed representation" of an item. I.e., in Matlab you say
[1, 2, 40 + 2]
ans = 1 2 42
In CL, doing the simple thing, you get
cl-prompt> [1 2 (+ 40 2)] [1 2 42]
but
cl-prompt> #(1 2 (+ 40 2)) #(1 2 (+ 40 2))
So, suppose you have your [ … ] reader macro, would you have it work "functionally" or "quoting-ly" (for want of a better word)? I am curious. Note that the Matlab-style version would not break referential transparency if you did not have mutations.
I struggled with this very question in Antik (grid syntax with #m). What I decided was it should mimic CL #(, i.e., not evaluate. For evaluation, I have function(s), particularly #'grid, so
ANTIK-USER> (setf *default-grid-type* 'foreign-array) FOREIGN-ARRAY ANTIK-USER> (grid 1 2 (+ 40 2)) #m(1.000000000000000d0 2.000000000000000d0 42.000000000000000d0)
(Note #'grid doesn't take as arguments any options like the grid type, just elements, but there are other functions that will.) My reasoning was mainly to be consistent with CL, but also somehow a reader macro triggering an evaluation seemed wrong; a function was the most appropriate way to do that. I can't recall right now the problem that caused me to switch (before, it did do evaluation), but it was a mess and this was the easiest way to clean it up.
This evaluation problem as per Liam's description is common in statistical computation (and numerical computation, from Marco's example, but I'm more familiar with the statistical domain, ie computations in R) when it is possible that you'd like to hold off on an evaluation as long as possible, since you might not need it.
(of course, if you are doing memoization and under a reasonable range of circumstances, then you might as well compute as long as you aren't blocking the interactive activity for too long).
I think that I agree in general with Liam's approach, of making it explicit. But the problem, as Marco is pointing out, is that often it is just convenient and follows the principle of least surprise if it is just evaluated. I'd argue that this principle holds for only a few cultures of data analysts, and that maintaining it is potentially at high cost, in the sense that it doesn't force the analyst to think a bit about what they are doing and what the cost (computation, data centrality, etc) is. The payout (negative) doesn't occur too often, but when it does, it bites hard...
best, -tony
blindglobe@gmail.com Muttenz, Switzerland. "Commit early,commit often, and commit in a repository from which we can easily roll-back your mistakes" (AJR, 4Jan05).
Drink Coffee: Do stupid things faster with more energy!
Marco Antoniotti antoniotti.marco-Dh89VHlp6JQSLDncKRkoXw@public.gmane.org writes:
Dear all,
I was fooling around with reader macros to implement some - let's say
- "tuple" syntax.
Now, I am just curious about the general thinking on this.
First of all, let's note that the problem here in the conflating of the "constructor" with the "printed representation" of an item. I.e., in Matlab you say
[1, 2, 40 + 2]
ans = 1 2 42
In CL, doing the simple thing, you get
cl-prompt> [1 2 (+ 40 2)] [1 2 42]
but
cl-prompt> #(1 2 (+ 40 2)) #(1 2 (+ 40 2))
So, suppose you have your [ … ] reader macro, would you have it work "functionally" or "quoting-ly" (for want of a better word)? I am curious. Note that the Matlab-style version would not break referential transparency if you did not have mutations.
The question is whether this is a syntax that is printable readably or not.
As you constated, [1 2 (+ 40 2)] prints as [1 2 42] and [1 2 42] reads as [1 2 42], so far so good.
How does [1 2 '(+ 40 2)] print? If it prints with *print-readably* bound to t as [1 2 '(+ 40 2)] then it's ok. If it prints as [1 2 (+ 40 2)] then you didn't respect the *print-readably* condition.
The data structure built when reading [1 2 '(+ 40 2)] could also be printed quite differently depending on *print-readably*.
With *print-readably* = t ['(+ 40 2)] could print as #((+ 40 2)) With *print-readably* = nil ['(+ 40 2)] could print as [(+ 40 2)] (or some other alternative).
Finally, it's not so hard to introduce the needed quotes when printing readably a readable form that works "functionally".
IMO, the printable readably property is a good thing and should be provided as much as possible. If your tuples are not just lists or vectors, then you can provide a print-object method to do it nicely:
cl-user> (setf *print-readably* t) T
cl-user> (let ((x 33)) [1 2 (+ 40 2) x :x]) [1 2 42 33 :X]
cl-user> [1 2 42 33 :X] [1 2 42 33 :X]
cl-user> [1 2 '(+ 40 2) 'x ':x] [1 2 '(+ 40 2) 'X :X]
cl-user> [1 2 '(+ 40 2) 'X :X] [1 2 '(+ 40 2) 'X :X]
cl-user> (setf *print-readably* nil) NIL
cl-user> [1 2 '(+ 40 2) 'X :X] #<TUPLE (1 2 '(+ 40 2) 'X :X) #xB16B00B5> ; but it could also print readably