Re: Minor syntax improvements (proposal)

mikel evins <[email protected]>
Newsgroups gmane.comp.lang.dylan.gwydion.devel
Message-ID <[email protected]>
On Feb 28, 2013, at 11:55 AM, Carl Gay <[email protected]> wrote:

> 1) allow the use of the keyword "local" (in addition/substitution to
> "let") to define a local variable. The word let, in itself, does not
> convey any meaning on locality, and in theory could also apply (for
> those who are not familiar with the language) to any type of variable.
> So it is a bit misleading, or at least not so much useful. The keyword
> local is much better, because it is self-explanatory.
> 
> I think "let" is fairly obvious (at least for nerdy English speakers) because it is used verbally in math and has a history in many programming languages.  Plus, it saves two characters, and who can argue with that‽
> 
> This is interesting though.  We do already have a "local" reserved word for introducing local methods.  http://opendylan.org/books/drm/Functions_Overview#IX-771  But why is it separate from "let"?  I dunno!  F# uses "let" for both.  Here are the three syntaxes:
> 
> local method m() #t end;
> let var = val;
> let handler <error> = method(cond, next) ... end;
> 
> I wonder why they didn't use "let method true() #t end" instead.

Before Mike Kahl designed the infix syntax, the phrase "local method" was unknown in Dylan. A method was an object, just like any other object. You created one like this:

(method (x) (* 2 x))

There's a method that doubles its argument.

s-expression Dylan didn't use the name "let" for variable binding; its lexical binding form was called "bind":

(bind ((x 5)
          (y (+ x 1)))
  (* x y))

Mike's syntax leans on Pascal and Modula-2 for its flavor. In those languages, talking about a "local method" sort of makes sense, because proceudres are not first-class objects, and you can't create one without simultaneously specifying the scope it lives in. That's not true of Dylan, of course; a method's jsut a value like any other value. For that reason, I think the use of "local" for methods that are bound in a local scope is misplaced, and perhaps even misleading. There's nothing "local" about the method--only the local name it's bound to.

I don't think "bind" was an improvement on "let", though. It's just as jargony, with less history and less common usage. As Carl says, anyone with any memory of math classes will remember how "let" is used to introduce variables, and it's widely used in functional languages for the same purpose.

> 2) Simplify the syntax of assignment operators, for the sake of
> consistency and simplicity. In all cases where an assignment is taking
> place, I propose that only one operator should be used.
> I fail to see the reason why = is used at all, in addition to :=
> I am probably missing something, but the point is: whatever the
> rationale for using =, i.e. yet another operator, in addition to :=,
> is this really justified in terms of economy of the language? I am not
> talking only in terms of compiler economy, but also in terms of
> programmer's mental economy... In sum, it would be much simpler to
> have only one assignment operator, and := is of course the best
> choice, because it is not ambiguous, whereas = is commonly used by
> many programmers for equality testing.
> 
> Honestly not sure on this one.  Conceptually "let x" is different from assignment since it's creating a new binding, but that's not very convincing.  I think this change would be a step sideways at best though.
>  

It's more than a conceptual difference; it's a practical difference with practical consequences. 

Binding a lexical variable means that any existing variable in the enclosing scope is unaffected by the binding; assignment means that its value is changed.

A let binding is equivalent to a lambda binding; in fact, you can implement the simple form of Lisp's let as a macro that expands to lambda:

(let ((x 3))
   (* 2 x))

is just a different way of writing

((lambda (x) (* 2 x)) 
   3)

Suppose you have some variable x that is bound to "foo" in either the global or an enclosing lexical scope, and suppose you capture that lambda in a variable:

(define frob (lambda (x) (* 2 x)))

If you call (frob 5), you're going to expect frob to return 10, because you're going to expect x to have the value 5 in frob's body. If someone in another thread comes along and sets the enclosing x to another value, it would be a very unpleasant surprise if that affected your frob call. 

Fortunately, you don;t have to worry about that, because Dylanuses lexical scoping for its variables; but that means assignment and binding must be different. If let just did a temporary assignment (that is, if x were what Lisp calls a special variable, or what Scheme calls a fluid variable) then in a mutlithreaded environment you could not rely on x having the value that let gave it, because the value could be changed by a set! in between any two instructions.

The distinction between assignment and binding is subtle and maybe even esoteric, but it's practical and significant, too.
_______________________________________________
hackers mailing list
[email protected]
https://lists.opendylan.org/mailman/listinfo/hackers
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.