Code Comments
Programming Forum and web based access to our favorite programming groups.
I'm using a couple of notational conveniences which
I like. Both involve "calling" data, so they can't
be defined in R5RS scheme. I know that several
implementations do allow these to be defined; I
think it would be an excellent thing to include in
a new standard.
Other people may think I should go wash out my head
because I'm giving function semantics to data and
messing up their domain theory. If so, that's okay.
But at least I thought I'd run it up the flagpole
and see if anybody else likes it.
#1: vectors and strings are now functions.
(a-vector 6) <=> (vector-ref a-vector 6)
(a-string 5) <=> (string-ref a-string 5)
examples:
(#(1 2 3 4) 3) => 4
("the quick brown fox" 2) => #\e
One other thing which I haven't quite decided
whether I like yet is for arrays: It would make
an n-dimensional array take n integer arguments
and work as array-ref; but calling an integer
with the array as an argument would act as a
"universal accessor", indexing into it as though
it were a vector (one-dimensional array).
This is probably not ready for standardization
yet because there's not even a fully hammered out
standard for non-vector arrays and, eg, a read-write
format for a non-vector array as a datum. In the
following I use an external notation for arrays where
the order of an array slice is indicated by the number
of hashes preceding its opening paren. I find this
more visually useful than most array references because
the hashes line up making a visual "frame" for the
structure of the arrays.
#2 arrays and nonnegative integers are now functions too.
(an-array 2 3) <=> (array-ref an-array 2 3)
(4 an-array) <=> (vector-ref (array->vector an-array) 4)
examples:
(##( #(1 2 3)
#(4 5 6)
#(7 8 9)) 0 2) => 3
(5 ##( #(1 2 3)
#(4 5 6)
#(7 8 9))) => 6
I support other syntactic extensions involving calling
data too, but most of them you'd probably dismiss as
crazy talk, and they actively defeat any attempt to make
any data structure opaque, so I expect the OO partisans
to hate them. So rather than starting that flamefest with
no hope whatsoever of consensus, I thought I'd throw
these relatively conservative bits of syntactic sugar
out there and see if anybody else has a sweet tooth.
Bear
Post Follow-up to this message> I support other syntactic extensions involving calling
> data too, but most of them you'd probably dismiss as
> crazy talk, and they actively defeat any attempt to make
> any data structure opaque, so I expect the OO partisans
> to hate them. So rather than starting that flamefest with
> no hope whatsoever of consensus, I thought I'd throw
> these relatively conservative bits of syntactic sugar
> out there and see if anybody else has a sweet tooth.
Hmm.
(#(1 2 3 4) +) -> 10
(#("red" "yellow" "green" "blue") gtk-listbox-add) -> You'll know.
((list 1 2 3 4) (list 5 4 3)) -> (1 2 3 4 6 4 3)
Isn't this just syntactic sugar or notational conveniance?
Post Follow-up to this message> Isn't this just syntactic sugar or notational conveniance? Sorry, You already mentioned that.
Post Follow-up to this messageRay Dillinger wrote:
> ...
> #1: vectors and strings are now functions.
>
> (a-vector 6) <=> (vector-ref a-vector 6)
> (a-string 5) <=> (string-ref a-string 5)
>
> examples:
>
> (#(1 2 3 4) 3) => 4
> ("the quick brown fox" 2) => #\e
> ...
> I thought I'd throw
> these relatively conservative bits of syntactic sugar
> out there and see if anybody else has a sweet tooth.
I am
as to why you call this syntactic sugar. Would you please
care explaining?
Aziz,,,
Post Follow-up to this messageAbdulaziz Ghuloum wrote: > Ray Dillinger wrote: > > > > I amas to why you call this syntactic sugar. Would you please > care explaining? > It's just a different and more convenient syntax for something that there's already a way to do. Bear
Post Follow-up to this messageRay Dillinger wrote: > Abdulaziz Ghuloum wrote: > > It's just a different and more convenient syntax for > something that there's already a way to do. I see it differently. Syntactic sugars include let, letrec, or, and, cond, case, and so on. All of these can be defined in terms of the primitive syntax forms: lambda, if, quote, procedure-application, and so on. What you're proposing changes the way application works. So, instead of application having one meaning; it now has a meaning that depends on the operator. I don't see this as syntactic sugar at all, rather, I see it as a change of semantics of application. So, an environment-passing/continuation-passing interpreter that was defined as (define E (lambda (expr env k) (cond .. [(application? expr) (E (first expr) env (lambda (rator) (E* (rest expr) env (lambda (rand*) (apply-procedure rator rand* k)))))] ..))) should now be written as: (define E (lambda (expr env k) (cond .. [(application? expr) (E (first expr) env (lambda (rator) (E* (rest expr) env (lambda (rand*) (cond [(procedure? rator) (apply-procedure rator rand* k)] [(vector? rator) (k (vector-ref rator (car rand*)))] [(list? rator) (k (list-ref rator (car rand*)))] .. [else ???] )))))] ..))) Is there a way to define your proposal without changing the semantics (or the interpreter) of scheme? Aziz,,,
Post Follow-up to this messageRay Dillinger <bear@sonic.net> writes:
> I'm using a couple of notational conveniences which I like. Both involve
> "calling" data, so they can't be defined in R5RS scheme. I know that
> several implementations do allow these to be defined; I think it would be
> an excellent thing to include in a new standard.
>
> Other people may think I should go wash out my head because I'm giving
> function semantics to data and messing up their domain theory. If so,
> that's okay. But at least I thought I'd run it up the flagpole and see
> if anybody else likes it.
I don't much like this conflation of function application with other
operations, but for software engineering reasons rather than problems with
domain theory.
My basic complaint is that these proposals would make certain kinds of
errors much harder to detect. In code that I've written and maintained,
there tends to be a non-trivial number of applications with a non-trivial
expression in operator position. If I've screwed up somewhere and this
expression returns a value that is neither a function nor a continuation, n
R5RS implementation would signal an error immediately upon evaluating the
application.
Under your proposals, though, I wouldn't get that error if my bug caused
the expression to return a vector---even though I expected a function. I
don't like that very much.
Don't get me wrong -- I'm not at all opposed to finding more concise syntax
for vector references and structure references (for those implementations
that support some sort of structure/record type). I just don't like the
idea of conflating it with application.
As a side note, I think that my objection only applies to a
dynamically-typed language like Scheme. The presence of an ML-like static
type system would help avoid the kind of problem I described above, even if
you conflated vector dereference and function application---so long as you
kept ('a vector) and (int -> 'a) different types.
Richard
Post Follow-up to this messageAbdulaziz Ghuloum wrote: > Ray Dillinger wrote: > > > > I see it differently. Syntactic sugars include let, letrec, or, and, > cond, case, and so on. All of these can be defined in terms of the > primitive syntax forms: lambda, if, quote, procedure-application, and so > on. > > What you're proposing changes the way application works. So, instead of > application having one meaning; it now has a meaning that depends on the > operator. I don't see this as syntactic sugar at all, rather, I see it > as a change of semantics of application. <clip> > Is there a way to define your proposal without changing the semantics > (or the interpreter) of scheme? Probably not. You could implement it in R5RS, but it would involve redefining all the primitive routines that work with these types to take closures and call them to get the actual values. Then you could have other calls to the closures that do these other things. But, effectively, that would be writing a new interpreter, with new semantics. Fundamentally, every value has evaluation semantics, quote semantics, and call semantics. In (standard) scheme the evaluation semantics of values other than symbols and cons cells is to return themselves, the evaluation semantics of symbols is to return a variable value, the evaluation semantics of cons cells is to evaluate the car and cdr, then call the results of evaluating the car with the results of evaluating the cdr as the argument list, and the call semantics of all non-procedure values is to signal an error. Standard constructs like define allow us to create procedure values with novel call semantics. But nothing in R5RS allows us to assign call semantics by type to other constants. This is the objection I thought people would raise; I'm messing with the simplified domain theory that underlies scheme semantics. Bear
Post Follow-up to this messagePowered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.