Some suggestions on Chapter 1 (abstract -anaconda)

22 views
Skip to first unread message

JuanManuel Gimeno Illa

unread,
Jun 22, 2012, 3:19:15 AM6/22/12
to fp...@googlegroups.com
Hi Brian,

    I've read chapter 1 and I have some suggestions:

    - Use load-file instead of load (and you can avoid the explanation about file extension). 

    - I was confused with the using of list* on my-apply. sequence is already a sequence, so you can cons on it. 

    - In your explanation of evaluation it seems that the element in the functional position can be evaluated "in parallel" with the other elements in the list. I would have explicily said tha the first element in the list is evaluated and, if it is a function value, then the rest is evaluated and next the function value is applied. Some of this is implied when you explain special forms after, but it would be more clear to detail it at the beginning.

    - Try not to use the name of a built-in such as list or seq as a parameter name (or variable). Built-ins are namespaced, so you can always reach them, but code gets more difficult to read if you use these names with other meanings. I'm referring to (def second (fn [list] ____)) on page 17, and (prefix-of? candidate seq) on page 26 (the same applies to some of the functions you describe at the beginning of the same page).

     Waiting for the next chapters to come,

     Juan Manuel

 

Brian Marick

unread,
Jun 24, 2012, 7:23:17 PM6/24/12
to fp...@googlegroups.com

On Jun 22, 2012, at 2:19 AM, JuanManuel Gimeno Illa wrote:
> - Use load-file instead of load (and you can avoid the explanation about file extension).
>

Done.


> - I was confused with the using of list* on my-apply. sequence is already a sequence, so you can cons on it.

Yes, but that works because (cons function [1 2 3]) produces a seq *and* because `eval` treats sequences like lists. It seemed likely that explaining all that would be confusing to a novice. So I wanted some way to write code where the "what about vectors?" question would be explicitly answered by code. Hence the little white lie about `list*` (which actually produces a seq -- but the name suggests what I think is less confusing to think).

If I could avoid sequences entirely until the chapter on laziness, I would, but the word is too ubiquitous in doc strings.

>
> - In your explanation of evaluation it seems that the element in the functional position can be evaluated "in parallel" with the other elements in the list. I would have explicily said tha the first element in the list is evaluated and, if it is a function value, then the rest is evaluated and next the function value is applied. Some of this is implied when you explain special forms after, but it would be more clear to detail it at the beginning.

My hunch: readers coming from object language will not have the possibility of parallelizing evaluation at the front of their mind, so they'll be assuming left-to-right sequential evaluation anyway.

When I reread the chapter next, after I've had some time to forget what I was thinking about while I wrote it, I'll see if I think I can work in the order of evaluation.

>
> - Try not to use the name of a built-in such as list or seq as a parameter name (or variable). Built-ins are namespaced, so you can always reach them, but code gets more difficult to read if you use these names with other meanings. I'm referring to (def second (fn [list] ____)) on page 17, and (prefix-of? candidate seq) on page 26 (the same applies to some of the functions you describe at the beginning of the same page).

I've been debating this internally. On the one hand, the way that you can shadow core functions is a good reinforcement of the point that functions are not special and that a function's name is not somehow intrinsically part of the function. (That separation is why I'm not using `defn`.)

On the other hand, I don't want to put *every* cool fact or consequence in the book.

In my own programming, I do avoid parameters with the same name as built-ins, but that leads to names like `lst` or `klass`, which are annoying in their own right. So I was hoping that some fraction of novices would see that function definition and wonder "what on earth would the following mean?"

(def x [list] (list list))

... and perhaps gain a deeper understanding, and every other novice wouldn't notice it. Only people who already know the difference between a Lisp-1 and Lisp-2 would have a visceral reaction --- Danger! Danger! --- when they saw the parameter name.

I could be convinced otherwise.

-----
Brian Marick, Artisanal Labrador
Now working at http://path11.com
Contract programming in Ruby and Clojure
Occasional consulting on Agile


JuanManuel Gimeno Illa

unread,
Jun 25, 2012, 3:18:42 AM6/25/12
to fp...@googlegroups.com


On Monday, June 25, 2012 1:23:17 AM UTC+2, Brian Marick wrote: 

On the other hand, I don't want to put *every* cool fact or consequence in the book.

In my own programming, I do avoid parameters with the same name as built-ins, but that leads to names like `lst` or `klass`, which are annoying in their own right. So I was hoping that some fraction of novices would see that function definition and wonder "what on earth would the following mean?"

I sometimes use "Smalltalk" naming: aList, aColl, aSeq. It's not very clojuresque, but I find it better than l, lst, s, sq, etc.

    (def x [list] (list list))

... and perhaps gain a deeper understanding, and every other novice wouldn't notice it. Only people who already know the difference between a Lisp-1 and Lisp-2 would have a visceral reaction --- Danger! Danger! --- when they saw the parameter name. 
I could be convinced otherwise.

Me too :-)

Juan Manuel 
Reply all
Reply to author
Forward
0 new messages