[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: orthogonality and generalized references (was Re: Zen of Python)
- To: "Matthias Felleisen" <address@hidden>
- Subject: RE: orthogonality and generalized references (was Re: Zen of Python)
- From: "Todd Proebsting" <address@hidden>
- Date: Mon, 27 May 2002 19:52:41 -0700
- Cc: "Kragen Sitaker" <address@hidden>, <address@hidden>
- Sender: address@hidden
- Thread-index: AcIF5n0iQN/8K+jwQPSuTqcKk9Q/9QACuisg
- Thread-topic: orthogonality and generalized references (was Re: Zen of Python)
Hi, Matthias. Actually, it's precisely my point that anybody versed in
Icon will immediately recognize the sequence of success and failure
computations because success/failure is central to Icon. By learning to
reason about success and failure as primitive/essential/fundamental
notions, an Icon programmer feels comfortable with them and can exploit
them to their advantage.
(I would guess that you'd argue something similar about explicit
higher-order programming, continuations, etc. Once you feel comfortable
with them, their power is yours to exploit.)
You can obviously argue that one *can* synthesize success/failure
computations from other primitives in Scheme. Absolutely correct. But,
I'd argue that the unfortunate thing is that one *must* synthesize them
to have them, thereby raising the cost of exploiting the concept. I
simply think that it's unfortunate that success/failure computations
must be synthesized in non-goal-directed languages, thereby minimizing
the likelihood of them being used effectively.
Cheers,
Todd
-----Original Message-----
From: Matthias Felleisen [mailto:matthias@ccs.neu.edu]
Sent: Monday, May 27, 2002 6:25 PM
To: Todd Proebsting
Cc: Kragen Sitaker; ll1-discuss@ai.mit.edu
Subject: RE: orthogonality and generalized references (was Re: Zen of
Python)
Todd, is Icon's symmetry of success and failure really the proper path
here? Isn't it the case that you want something like
(hash-table-get HT 'foo
; failure thunk:
(lambda () (hash-table-put! HT 'foo 42))
so that the reader recognizes the sequence of success and fail
computations?
-- Matthias
At Mon, 27 May 2002 17:57:55 -0700, "Todd Proebsting" wrote:
> Ages ago I posted to this list about goal-directed evaluation in Icon.
> This "ifAbsentPut" discussion will, I hope, allow me to express
> another advantage of goal-directed evaluation. In Icon, the
> ifAbsentPut idiom is the following simple expression---Icon has only
> expressions, and not statements.
>
> /dict["foo"] := 42
>
> To understand this statement, you must understand the unary '/'
> operator and the notion of goal-directed evaluation. The '/' operator
> computes the l-value (if one exists, otherwise the r-value) of its
> operand IFF the r-value is not null. If the r-value is null, then the
> operation fails. With goal-direction, an operand failing causes its
> parent operation to do whatever it is supposed to do when the operand
> fails. (The rules for what to do are simple and regular, but I'm not
> going to go into them here.)
>
> In this case the parent is the assignment operator, which itself will
> fail when its left operand fails. If and when the right operand and
> left operands have both succeeded, the assignment takes place and the
> r-value is produced as a value.
>
> So, the assignment above will assign the value 42 to dict["foo"] when
> dict["foo"] is null and simply fail when dict["foo"] is non-null.
> Note that the l-value is computed only once.
>
> The '/' operator can, of course, be applied to any expression. Any
> Icon programmer would recognize the idiomatic use of '/' above. I
> find it superior to the other schemes that I've seen.
>
> I wish other languages exploited the fundamental difference between
> success and failure that is essential to Icon. It's awkward to code
> your way around their absence in other languages.
>
> Todd
>
> -----Original Message-----
> From: Kragen Sitaker [mailto:kragen@pobox.com]
> Sent: Monday, May 27, 2002 4:56 PM
> To: ll1-discuss@ai.mit.edu
> Subject: orthogonality and generalized references (was Re: Zen of
> Python)
>
>
> Avi Bryant writes:
> > [in Ruby]
> > dict['foo'] ||= 42
> > [in Smalltalk, "extremely regular and explicit"]
> > dict at: 'foo' ifAbsentPut: [42].
> > ...
> > What's the equivalent Python idiom? My guess is that it will be
> > either less regular, or less explicit, or both. I'm not trying to
> > pick on Python, I'm just trying to point out that there is no simple
> > relationship between regularity, explicitness, and succinctness;
it's
> > entirely possible to have all three.
>
> Python uses roughly the Smalltalk approach, although (like Perl) it
> doesn't provide a convenient way for you to avoid evaluating the
> default value in the case that the value is already present:
> dict.setdefault('foo', 42)
>
> I don't quite understand what you mean by "regular" or "explicit"; the
> Ruby/Perl idiom is less explicit, I agree, but it appears to me to be
> more regular --- the Smalltalk/Python idiom here is to use a
> special-purpose method, while the Ruby/Perl idiom is a combination of
> three orthogonal language features that have nothing to do with
> dictionaries or hashes: the boolean 'or' operator's return value, the
> false result of looking up a nonexistent index in a dictionary or
> hash, and the augmented assignment operators. As a result, you can
> also say (in Perl):
>
> $x ||= 42; # ordinary variable
> $y[3] ||= 42; # list reference
>
> Common Lisp has the notion of a "generalized reference", such as
> (gethash "foo" dict), which can be set with setf or read by
> evaluation; and it has boundp and makunbound, but they only work on
> symbols, not generalized references. In a CL dialect where boundp and
> makunbound (somehow --- they standardly evaluate their arguments, so
> (boundp (gethash "bar" x)) will tell you whether the symbol (gethash
> "bar" x) returns is bound or not) worked on generalized references,
> you could write a setdefault macro that would allow you to say things
> like this:
>
> (setdefault (gethash "foo" dict) 42)
> (setdefault x 42)
> (setdefault (nth 3 y) 42)
>
> giving you the same level of regularity and orthogonality you have in
> Perl and Ruby, along with the same level of explicitness you have in
> Python (and, arguably, Smalltalk, although I think at:ifAbsentPut: is
> more explicit than setdefault).
>
> (I don't know Common Lisp; apologies for any mistakes.)
>
> I wish I had a language where I could define this "setdefault"
> operation; it requires Common Lisp's ability to define new operations
> on generalized references (for example, with macros; you can do it
> crudely in C++ with a reference or in Forth with a raw memory address)
> along with Python's ability to get, set, undefine, or check
> definedness of generalized references. [0] Is there such a language?
>
>
> [0] Python conflates providing an initial value and replacing an
> existing value with a new value, unfortunately, and provides 'check
> definedness' by raising an exception when you try to get an undefined
> value. Also, Python's generalized references are variables, object
> attributes (x.y), and indexing expressions (x[y]), not general
> function calls; this sounds more limiting than it is.
>
> --
> /* By Kragen Sitaker, http://pobox.com/~kragen/puzzle2.html */ char
> a[99]=" KJ",d[999][16];main(){int
> s=socket(2,1,0),n=0,z,l,i;*(short*)a=2;
>
if(!bind(s,a,16))for(;;){z=16;if((l=recvfrom(s,a,99,0,d[n],&z))>0){for(i
> =0;i<n;
> i++){z=(memcmp(d[i],d[n],8))?z:0;while(sendto(s,a,l,0,d[i],16)&0);}z?n
> i++++
> i++:0;}}}